Posts filed under ‘Uncategorized’

Check in Java web app if user is logged in in Rails web app

I have a Rails application where users can log in and do stuff. For one of the actions a user can perform, I actually use a Java web application integrated in the Rails application. Because I don’t want a malicious user that is not logged in to the application to surf directly to the Java application, I need a system where my Java application is only accessible for users logged in to the Rails application. I used a Servlet Filter that contacts the Rails application in the background and asks if the user is logged in. Only then is the user allowed to proceed.

First I built an a controller in Rails with an action that checks if the user is logged in. In my application this is available at the url localhost:3000/session/check.

class SessionController < ApplicationController

def check

if session[‘user’].nil?

logged_in = false

else

logged_in = true

end

render :text => logged_in.to_s #just write true or false to the output

end

end

package be.vrt.medialab.filters;

Now I want my Java web application to first request the Rails session check and when it returns false it should redirect to the login page instead of serving the Java servlets. I used a Java servlet filter for this job. I created the filter in a separate project, here is the source code:

package be.vrt.medialab.filters;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.MalformedURLException;

import java.util.ResourceBundle;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServletRequest;

public class RailsAuthentication implements Filter {

FilterConfig filterConfig = null;

private ResourceBundle resources;

public RailsAuthentication() {

resources = ResourceBundle.getBundle(“config”);

}

public boolean getRailsResponse(String urlString,String cookie) {

// Open a URL connection.

java.net.URL url;

try {

System.out.println(“urlString=”+urlString);

url = new java.net.URL( urlString );

final java.net.URLConnection uconn = url.openConnection( );

if ( !(uconn instanceof java.net.HttpURLConnection) )

throw new java.lang.IllegalArgumentException(

“URL protocol must be HTTP.” );

final java.net.HttpURLConnection conn =

(java.net.HttpURLConnection)uconn;

// Set up a request.

conn.setConnectTimeout( 10000 ); // 10 sec

conn.setReadTimeout( 10000 ); // 10 sec

conn.setInstanceFollowRedirects( true );

conn.setRequestProperty( “User-agent”, “spider” );

conn.setRequestProperty(“Cookie”, “_ifip_rails_session=”+cookie+“;”);

// Send the request.

conn.connect( );

BufferedReader in = new BufferedReader( new InputStreamReader((InputStream) conn.getContent( )));

String inputLine;

inputLine = in.readLine(); // Process each line.

System.out.println(“rails returned: “+inputLine);

conn.disconnect( );

if (inputLine.equals(“true”)) {

//authentication successful: user is logged in

System.out.println(“authentication successful!”);

return true;

} else {

//authentication failed: user is not logged in

System.out.println(“authentication failed!”);

return false;

}

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException,ServletException {

String railsCheck =resources.getString(“RailsCheck”);

String invalidUrl=resources.getString(“InvalidUrl”);

HttpServletRequest request = (HttpServletRequest) req;

Cookie[] cookies = request.getCookies();

String rails_session_id = null;

for(int i=0;i<cookies.length;i++) {

Cookie cookie = cookies[i];

if (cookie.getName().equals(“_ifip_rails_session”)) {

rails_session_id = cookie.getValue();

}

}

if (rails_session_id == null) {

//authentication fails

System.out.println(“Autentication fails, no rails session id!”);

} else {

System.out.println(“Rails session id is “+rails_session_id);

//query rails app if this session id is from a logged in user

boolean valid_user =getRailsResponse(railsCheck,rails_session_id);

if (valid_user) {

// pass the request along the filter chain

chain.doFilter(request, response);

} else {

System.out.println(“valid_user=”+valid_user+“, redirecting to /RedirectServlet”);

ServletContext context =filterConfig.getServletContext();

context.getRequestDispatcher(“/RedirectServlet”).forward(request, response);

}

}

}

public void init(FilterConfig fConfig) throwsServletException {

// TODO Auto-generated method stub

filterConfig = fConfig;

}

}


I couldn’t find how to redirect to an external URL directly from within the servlet filter, so I just forwarded to a second servlet that has the sole job of redirecting to a certain URL (the login page):


package be.vrt.medialab;

import java.io.IOException;

import java.util.ResourceBundle;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public class RedirectServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

private ResourceBundle resources;

public RedirectServlet() {

super();

resources = ResourceBundle.getBundle(“config”);

}

protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {

String invalidUrl=resources.getString(“InvalidUrl”);

response.sendRedirect(invalidUrl);

}


protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {

String invalidUrl=resources.getString(“InvalidUrl”);

response.sendRedirect(invalidUrl);

}

}

import java.io.BufferedReader;

Now the only thing we have to do is place the classes in our web application and change the web.xml as follows:

<?xml version=“1.0” encoding=“UTF-8”?>

<web-appxmlns:xsi=http://www.w3.org/2001/XMLSchema-instance&#8221;xmlns=http://java.sun.com/xml/ns/javaee&#8221;xmlns:web=http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#8221;xsi:schemaLocation=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&#8221;id=“WebApp_ID” version=“2.5”>

<display-name>IfipUploader</display-name>

<welcome-file-list>

<welcome-file>TestPage.html</welcome-file>

<welcome-file>FormUpload.html</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<filter>

<filter-name>Rails Authentication</filter-name>

<filter-class>be.vrt.medialab.filters.RailsAuthentication</filter-class>

</filter>

<filter-mapping>

<filter-name>Rails Authentication</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<servlet>

<servlet-name>RedirectServlet</servlet-name>

<display-name>RedirectServlet</display-name>

<description>redirects to InvalidUrl</description>

<servlet-class>be.vrt.medialab.RedirectServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>RedirectServlet</servlet-name>

<url-pattern>/RedirectServlet</url-pattern>

</servlet-mapping>

<servlet>

<description>Extension of abstract class UploadServlet</description>

<display-name>UploadServletWithQueue</display-name>

<servlet-name>UploadServletWithQueue</servlet-name>

<servlet-class>be.vrt.medialab.upload.UploadServletWithQueue</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>UploadServletWithQueue</servlet-name>

<url-pattern>/UploadServletWithQueue</url-pattern>

</servlet-mapping>

</web-app>

import java.io.IOException;

Below are two logs from the Java web application:

Logged out: (the Rails session id is from a previous session and thus invalid)

Rails session id is BAh7CToQX2NzcmZfdG9rZW4iMVUyeFJWWWVzc1hUZFNPRDR2dkFUb3lONVFaQlJrVmsxR1h0VzVaS3RmUFU9Og9zZXNzaW9uX2lkIiUyOTg2NDc2NzY0N2RlMGU1OWExMTFiOTUwMTk0Zjg2MCIQaW5pdGlhbF91cmkiDS9tYW1taWUvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--41ae001042b16ee26966fc931d11719bc51d7b71
urlString=http://media.ibbt.be/mammie/session/check
rails returned: false
authentication failed!
valid_user=false, redirecting to /RedirectServlet

Logged in:

Rails session id is BAh7CiIJdXNlcm86CVVzZXIHOhZAYXR0cmlidXRlc19jYWNoZXsAOhBAYXR0cmlidXRlc3sdIg5qb2JfdGl0bGUiF1NpdGUgQWRtaW5pc3RyYXRvciIRb2ZmaWNlX3Bob25lMCIPdXBkYXRlZF9hdCIYMjAwOS0xMC0wOCAxMTo1OToxNiIKdGl0bGUiF3NpdGUgYWRtaW5pc3RyYXRvciIYb3JnYW5pc2F0aW9uX3JlZ2lvbjAiDXVzZXJuYW1lIgphZG1pbiIMY291bnRyeSIHQkUiGW9yZ2FuaXNhdGlvbl9hZGRyZXNzMCIHaWQiBjEiHG9yZ2FuaXNhdGlvbl9kZXBhcnRtZW50MCIWb3JnYW5pc2F0aW9uX2NpdHkwIhRhc3Npc3RhbnRfcGhvbmUwIg9maXJzdF9uYW1lIgphZG1pbiITaGFzaGVkX3Bhc3dvcmQiLWI0NzIwODY3MGU2YmU1ODdhNjE1YTcwZDMzZGRkYmVkNmNhMGNiZjAiD29mZmljZV9mYXgwIhFvcmdhbmlzYXRpb24wIg5sYXN0X25hbWUiFnRoZSBhZG1pbmlzdHJhdG9yIhBhZmZpbGlhdGlvbjAiFm9yZ2FuaXNhdGlvbl90eXBlMCIPY3JlYXRlZF9hdCIYMjAwOS0xMC0wOCAxMTo1OToxNiIKZW1haWwiHmthcmVsLmJyYWVja21hbkBnbWFpbC5jb20iEW1vYmlsZV9waG9uZTAiHW9yZ2FuaXNhdGlvbl9wb3N0YWxfY29kZTAiGW9yZ2FuaXNhdGlvbl9jb3VudHJ5MDoPc2Vzc2lvbl9pZCIlMjk4NjQ3Njc2NDdkZTBlNTlhMTExYjk1MDE5NGY4NjA6EF9jc3JmX3Rva2VuIjFVMnhSVlllc3NYVGRTT0Q0dnZBVG95TjVRWkJSa1ZrMUdYdFc1Wkt0ZlBVPSIQaW5pdGlhbF91cmkiDS9tYW1taWUvIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--9857ba6780010c041df44eabbfa5f3943ecbe218
urlString=http://media.ibbt.be/mammie/session/check
rails returned: true
authentication successful!

Advertisements

October 20, 2009 at 11:56 am 1 comment

Jeditable JQuery plugin on Rails

The Jeditable JQuery plugin is an awesome piece of javascript code that allows the users of your webpage to just click some text and edit it in place. So instead of having an “edit” page for your data, you let the user edit directly from the “show” page.

The usage of the plugin is very easy, as explained on their homepage. You just wrap the editable text in a div with class “edit” and add the folowing piece of javascript code:

$(document).ready(function() {
$(‘.edit’).editable(‘http://www.example.com/save.php&#8217;);
});
$(document).ready(function() {

     $('.edit').editable('http://www.example.com/save.php');

 });

This will make the text clickable. When the user clicks on it, the text changes to an input field with a submit button, which saves the new data to save.php.

edit_in_place

I wanted to use the Jeditable script in my Rails application, but I ran into some difficulties along the way. After some frustrating digging around I came to the following:

I added an update_field action to my controller that allows changing a single value and returns the value of that field:

  # called after editing an item
  # PUT /items/1
  # PUT /items/1.xml
  def update_field
    @item = Item.find(params[:item][:id])
    dc_ds = params[:item][:dc_ds]
    #read and write the DC datastream...
    @dc_ds = DC_datastream.new(:id => params[:item][:id])
    puts 'params update:'
    pp params

    keys = params[:dc_datastream_solr].keys
    k = keys.first
    #params[:dc_datastream_solr].each_key do |k|
      @dc_ds.send k.to_s+'=',params[:dc_datastream_solr][k]
    #end    

    @dc_ds.save_to_fedora

    render :text => params[:dc_datastream_solr][k]
  end



In the layout of the item we set the javascript AUTH_TOKEN variable so we can correctly set the authenticity token in the requests sent to Rails by JQuery:
<%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %>



And this is the javascript that will work on e.g. <div class=”edit_area” id=”theid” name=”thename” />

//the each is needed because we need to read id and name of each item
$('.edit_area').each(function(i) {
  $(this).editable('./update_field/<%=@item.id%>', {
    type	:	'textarea',
    name	:	$(this).attr('name'),
    id		:	$(this).attr('id'),
    cancel	:	'Cancel',
    submit	:	'OK',
    indicator:	'Saving...',
    tooltip	:	'Click to edit...',
    submitdata:	{_method: "put", "item[id]": "<%=@item.id%>",authenticity_token: AUTH_TOKEN},
    rows:		10
  });
});

I iterate explicitly over all the divs on the page with class edit_area so I can set the name and id of this editable object to the name and id attribute of the respective div’s.

The submitdata line does a few things:

submitdata:	{_method: "put", "item[id]": "<%=@item.id%>",authenticity_token: AUTH_TOKEN},

_method: "put" is Rails' way of simulating an HTTP PUT verb via an HTTP POST. 

"item[id]": "<%=@item.id%>" passes the item's id back to Rails.

authenticity_token: AUTH_TOKEN includes the authenticity token in the request that is sent. 



October 13, 2009 at 7:07 pm 2 comments

Webdesign: show content on top of Flash or Silverlight component

I started playing with JQuery last week and used the Boxy plugin to display a dialog window to the user while disabling all other components. In the background it uses CSS’s z-index property to accomplish this. At least.. almost all components, because as you can see in the video below the flash movie kept appearing on top of the Boxy window. In a later test I noticed the same thing happens for Silverlight components.

problem

Here is how to fix it:

Flash

Flash has a “wmode” parameter which you have to set to “opaque” for the z-index style to have an effect. For instance for the Flash JWPlayer:

<script type='text/javascript'> 

	var s1 = new SWFObject('player.swf','IFIPPlayer','400','300','9');

	s1.addParam('allowfullscreen','true');

	s1.addParam('allowscriptaccess','always');

	s1.addParam('flashvars','type=video&file=movie.flv');

	s1.addParam('wmode','opaque');

	s1.write('theplayer');

</script> 

Silverlight

Silverlight has a “windowsless” property which you have to set to ‘true’ for the z-index style to have an effect. For instance for the Silverlight JWPlayer:

<script type=”text/javascript”>
var cnt = document.getElementById(“player_http://ifip.test.ibbt.be/fedora/get/<%=@item.id%>/MAM_lowres”);
var src = ‘<%=ActionController::Base.relative_url_root%>/wmvplayer.xaml’;
var cfg = {
height:'<%=defined?(@flashplayer_height) ? @flashplayer_height : 300%>’,
width:'<%=defined?(@flashplayer_width) ? @flashplayer_width : 400%>’,
windowless:’true’
};
var ply = new jeroenwijering.Player(cnt,src,cfg);
</script>
<script type="text/javascript"> 

	var cnt = document.getElementById("theplayer");

	var src = '/wmvplayer.xaml';

	var cfg = {

		file:'movie.wmv',

		image:'thumb.jpg',

		height:'300',

		width:'400',

		windowless:'true'

	};

	var ply = new jeroenwijering.Player(cnt,src,cfg);	

</script> 

And a screenshot to prove it 🙂

solved

October 6, 2009 at 11:18 am Leave a comment

flash 10 on Ubuntu amd_64

230  sudo apt-get remove flashplugin-nonfree flashplugin-installer
233  tar xvf libflashplayer-10.0.32.18.linux-x86_64.so.tar.gz
234  sudo mv libflashplayer.so /usr/lib/mozilla/plugins/
Flashplayer 10 is not yet supported by Adobe for amd_64 Linux architectures, but they do have an alpha relase in their labs: http://labs.adobe.com/downloads/flashplayer10.html. Here’s how to install it (Thanks to these guys, only the download url has changed. ).
sudo apt-get remove flashplugin-nonfree flashplugin-installer
wget http://download.macromedia.com/pub/labs/flashplayer10/libflashplayer-10.0.32.18.linux-x86_64.so.tar.gz
tar xvf libflashplayer-10.0.32.18.linux-x86_64.so.tar.gz 
sudo mv libflashplayer.so /usr/lib/mozilla/plugins/

October 2, 2009 at 4:59 pm Leave a comment

Watching DVB-T television on my Ubuntu

As mentioned in the edit of my previous post, I got my DVB-T stick working without any big problems. Nevertheless here are the steps I took to get it fully working! The DVB-T stick is a Pinacle 72e dvb-t tuner usb stick.

1. Use Kaffeine in the beginning. It is the simplest DVB-T player. Scan for channels and play, that’s it.

2. Then I followed this guide to get MythTV working. MythTV is a more advanced mediaplayer than Kaffeine. It is especially good in working with TV capture cards and everything related (timeshifting, recording, pausing, …). It can even work with several capture cards. The disadvantage is that the configuration is a bit counterintuitive.. (but with the guide in your hands you’ll be safe)

3. I got a problem with my audio-jack, when I plugged in my speakers or a headphone, nothing happened. I used these steps to solve the problem.

4. You can select MythTV to run on a second display in the setup (select screen “1” instead of screen “0”).

5. My EPG (program guide) took the longest time to setup. The best way to go depends on the country in which you live. I live in Belgium and found the following approach to work well:

177  sudo apt-get install libc6-i386
178  sudo apt-get install lib32nss-mdns
179  mkdir ~/mc2xml
180  cd /home/karel/mc2xml/
182  ls
183  rm index.html\?h\=o9wxhzm
184  ls
185  chmod 755 mc2xml
186  sudo ./mc2xml -c us -g 10000
187  sudo ./mc2xml -c be -g 9000 -o xmltv.xml
188  ls
189  cat xmltv.xml
190  sudo ./mc2xml -c be -g 9000 -o xmltv.xml
191  sh myth_script.sh
192  ls
193  sudo sh myth_script.sh
sudo apt-get install libc6-i386
sudo apt-get install lib32nss-mdns
mkdir ~/mc2xml
cd /home/karel/mc2xml/
–> download mc2xml from http://mc2xml.110mb.com/ and save it in the created folder
chmod 755 mc2xml
sudo ./mc2xml -c be -g 9000 -o xmltv.xml
Then I used the script from this site to convert the channel names to something more readable and fill the MythTV database. My replacements file looks like this:
I203250.750821.microsoft.com/een
I217250.750822.microsoft.com/ketnet-canvas
Make sure you change the “xml tv channel id” in MythTV backend channel editor to the same one you selected in the replacements file (e.g., “een” or “ketnet-canvas”). Now everything should work and MythTV should show the program guide:
mythtv
tvinfo
Note that MythTV even shows the channel icons, which I find really cool (even MediaCenter couldn’t do that).

September 25, 2009 at 11:58 am 2 comments

Switched to Ubuntu!

My laptop was getting on my nerves again, acting slow and dodgy (even though I formatted it only a few months ago). I was feeling adventurous and decided to kick my Windows out of the hard drive and install Linux on it! Asking my friend Bert what is the best Linux distribution in his opinion, I was pointed at Ubuntu. So Ubuntu it is 🙂

6109ubuntu_logo

Not a day after deciding to clean up the computer I am happily using my Ubuntu. And the cool part is I can just keep using my favourite applications:

  • Pidgin chat client is included in Ubuntu by default
  • Virtualbox has a linux version. This will also allow me to run Windows in case I get homesick 😉
  • Dropbox for sharing my files between work and home
  • Xmind for creating mind maps and notes
  • Google Chrome (although it is not already stable, f.i. the security features don’t work yet)
  • Evernote (using Wine, a Linux app that allows you to install and run Windows applications)

I’m a bit afraid of my more exotic hardware (dvb-t stick, PIC development board, …) but haven’t tried it yet.. But very positive so far!

edit: I got my DVB-T stick working without problems :-). It’s a Pinacle 72e stick, and it is natively supported by Ubuntu. I used Kaffeine player to first test it and it found all my channels without problems. Than I got things working in MythTV using this guide.

September 10, 2009 at 9:17 pm Leave a comment

SuSe Yast hangs due to offline repositories

I had to install a package using Yast today, but every time I started the software management in Yast it froze, displaying ‘Downloading files’. After some digging around (I am no Linux expert), I found out Suse couldn’t find the package repositories that were configured on the machine.

I added some repositories by duplicating the files in /var/lib/zypp/db/sources and editing their URL and alias with vi. When querying zypper for the repositories they showed up immediately:

machine:/var/lib/zypp/db/sources # zypper sl

# | Enabled | Refresh | Type | Name                                     | URI

--+---------+---------+------+------------------------------------------+-----------------------------------------------------------------

1 | Yes     | Yes     | YaST | SUSE Linux Official Repo Open source     | http://download.opensuse.org/distribution/10.3/repo/oss/

2 | Yes     | Yes     | YaST | SUSE Linux Official Repo Non Open source | http://download.opensuse.org/distribution/10.3/repo/non-oss/

4 | Yes     | Yes     | YaST | SUSE LINUX 10.1                          | http://opensuse.hro.nl/opensuse/distribution/SL-10.1/inst-source
cp a727c04ccf8bec4dcfd5d093571e8abb nonopensour
When I opened the Software Management section in Yast now, it started downloading the files.

September 7, 2009 at 2:53 pm Leave a comment

Older Posts Newer Posts


Feeds

Articles to be written…

Twitter – kr3l

my del.icio.us

RSS Google Reader Shared Stuff

  • An error has occurred; the feed is probably down. Try again later.

RSS Listening to..

  • An error has occurred; the feed is probably down. Try again later.