Things to turn in at final

From MWCSWiki

Revision as of 01:50, 4 May 2007 by Sjone9ek (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

URL

http://rosemary.umw.edu/~ehols9do/filebrowser/

Summary of the purpose and major features

The project consists of a page that acts as an application. Upon first visit, the page will ask the user for his or her username and password. Upon login, the page will display the contents of that user's home folder on Rosemary. (Right now, though, the authentication is an issue and every user will be taken to a sandbox directory). The user can double click on a file, which will download that file to the local computer. When the user clicks on a directory, the page will display the contents of that directory. The files and directories can be shown in icon or list form. All of this happens asynchronously using Ajax. The user can also choose to upload files to the directory of his or her choosing.

The user can hover his or her mouse over the icons on the page to display a tooltip containing information about the files and directories. If the file is a text file, there will be a small preview of the contents of the file. This information is retrieved at the same time as the directory listing, and is then hidden in the background. The page also displays other information such as the size and permissions of files. This information is also available in the list view. Another feature will be the ability to drag-and-drop files and directories within the browser window to give the application a true desktop feel.

A guide to using our site

To login, use your Rosemary username and password. As of this writing, the system will authenticate you, but it will only bring you to a temporary sandbox.


Features of our site

Basics

When you first log in, you will be viewing your home directory. The address bar at the top will tell you where you are, with /home/ being your home directory. You can navigate the file structure by double clicking on directories. Each directory will have a ../ directory that will take you one level up. You can also click on a directory on the address bar to go up as many levels as you wish.

When you hover your cursor over a file, you will see some basic information about the file, such as name, size, and a preview if it is a text file. Double clicking a file will give you the option of downloading it. You can select an item with a single click. You can select multiple items by holding down shift or ctrl, just like in a desktop file browser. A menu with options is on the left side of the screen, and you can alternatively right click on files to access a menu.

Menu Options

View

In the upper-right part of the screen there is a button that you can press to change the view of the files. There are a list view and an icon view. The icon view is on by default.

Refresh

This refreshes the current directory. Shortcut key is 'R'.

Create Directory

Use this to create a new directory inside of the current one. This option will prompt you for a name. Shortcut key is 'N'.

Delete Items

Use this to delete all the items that you have selected. Shortcut key is 'delete'.

Copy Items

Use this to copy the selected files to another directory. You will be prompted to type in the directory that you wish to be the destination. Shortcut key is 'control C'.

Move Items

This works the same as copy, but it moves the file. You can also use this to rename files; just enter a new filename. Shortcut key is 'control X'.

Uploading files

To upload files to the current directory, use the form at the bottom-left corner of the screen. Select the file you wish to upload and click Submit. You must refresh the current directory in order to see the newly uploaded file.

Download Items

Use this to download all the selected files. Do not select too many files! You will be prompted for each individual file. Shortcut key is 'D'.

Documentation about file system layout

Our application only uses one page to do all of the work. The application actually manipulates the file system based on the actions of the user on the web page. The Javascript front end communicates with Perl scripts in the back end that do the actual work of applying the changes. Most of the operations were mirrored from their UNIX command line counterpart (Move = mv, Copy = cp). The hard part was in the context of the operations. Supplying the right directory and arguments to the commands in the proper situation (cp for moving a file, cp -r for moving a directory). The actual layout of the content in the screen was all dynamic, mirroring whatever was on the filesystem at the time.

List of features

Function/Feature Owned by Purpose Operation
Detect browser Elliott Project only supported in firefox, so make sure the user is not using IE checks against navigator.appName
Create Directories Everybody Allow the user to add directories. (Eric) The create directory feature was implemented on the back end by using the 'mkdir' command. The path of the file was passed to it and 'mkdir path' was called. (Elliott) Prompt alert grabs info. (Sam) Handled the interaction with the server by using a request.
Move/Copy files/directories Everybody Allow the user to move things around. (Eric) The move feature was implemented on the back end by using the 'mv' command. The copy feature was implemented on the back end by using the 'cp' command. The path of the file and the path of the destination were passed to it and 'cp path destination' was called. 'cp -r path destination' is called for directories. (Elliott) Confirm boxes display selected files and make sure user wants to preform the action and calls the function for each file. (Sam) Handled the interaction with the server by using a request.
Delete files/directories Everybody Allow the user to delete items. (Eric) The delete feature was implemented on the back end by using the 'rm' command. The path of the file was passed to it and 'rm path' was called. 'rm -r path' was called for removing directories. (Elliott) Confirm boxes displays selected files and call the delete function for each selected file. (Sam) Handled the interaction with the server by using a request.
Preview Files Sam/Eric Shows the header information to give a preview. (Eric) The preview feature was implemented on the back end by using the 'head' command. The path of the file was passed to it and 'head path' was called. The script checked to see if the file was a text file before calling head, binary files showed no preview. (Sam) Sent a request to the server for the head of the file.
Upload Files Eric Allow the user to upload files to their space. (Eric) The file uploads were another hard area of the project for security reasons. You are not allowed to submit a file to a web server through AJAX because of security concerns. A user could be tricked into selecting some file with sensitive data in it, and the server could automatically pull it from their browser without them knowing. However, there is a workaround for this. The form must be submitted to a hidden iFrame window within the page. The form is submitted to the hidden iFrame, and submitted without the page refreshing. This is how our file upload stuff works, but it is a hack.
Download Files Eric Allow the user to download files. We ran into problems with simple downloading of files because the file browser allows you to see files outside of the browsers web root. I fixed this problem by having a download.cgi script to which you pass the path of the file you want to download. The CGI script reads the file into memory and then outputs it back out over the HTTP request in a binary form. Setting the content-type of the file to application/x-download, this prompts the browser to offer the user a file to download instead of simply reading the binary file and displaying gibberish.
Make directories droppable Elliott Allow the user to drop files into a directory Used scriptaculous library
Make items draggable Elliott Give the application a more desktop feel Used scriptaculous library
Address Bar Elliott Allow the user to jump to directories and show current path Keeps running record of the current directory, then splits the name up by '/' and link them to loadDir for each path.
Username Function Eric Returns the current user so they can be displayed in the browser even on a page refresh. This was simply returning the username from the session on the back end.
Natural color scheme and layout of the whole window Sam Make user experience enjoyable All handled through CSS.
Details in list view Sam/Elliott Show information quickly (Elliott) Made calls to set up the div from the createIcon function (Sam) Modified CSS to display as a list.
Shortcut keys Elliott Give the application a more desktop feel Check the onkeypress event, filter out keys that are used for shortcuts
Selecting items Elliott Lets the user Select items in a variety of ways using shift and ctrl Set up the algorithm that decides what to select and filters out the ../ directory
Add creative commons logo and Get Firefox logo Sam Shameless advertising Grabbed some logos from the appropriate sites
Authentication Sam/Eric To keep your site secure. The backend part of this is explained in the "most difficult" aspects below (Sam) Sent a request to the server containing the user credentials.
Right-click menu Elliott Allow quick access to functions Used the library, added divs for menu items that onclick to the manu items in the regular menu. Also edited the library to allow the right click to select an item or keep items selected when used.

Link to source code

http://rosemary.umw.edu/~ehols9do/fb.zip

Three most difficult aspects of the project

Authentication (Eric)

Authentication was a large part of our project. The user needs to be authenticated to be able to work on their files as themselves. The authentication was a multi-step process. First the user has to be authenticated against the NIS server on paprika. Once that has been done, there must be some kind of HTTP session that keeps this authentication information. This is achieved with a cookie. This cookie then must be read on all the pages to prove the user is who they are. There must also be logout functionality so that another person using a computer after the user can't do things as the previous user.

The NIS authentication was hard to conceptualize, but once I got the idea down, it was easy to implement. There is an Net::NIS Perl module that allows for easily hitting NIS servers. The bulk of the work was accomplished in two lines of code, but figuring out what these two lines should be required hours of research:

my $domain = Net::NIS::yp_get_default_domain();
my ($status, $entry) = Net::NIS::yp_match($domain, "passwd.byname", $un); #where $un is the supplied username
#Got auth data, now simply check to see if what they supplied is right, and do the session/cookie stuff
my ($user, $hash, $uid, $gid, $gecos, $dir, $shell) = split(/:/, $entry);
if(crypt($pw, $hash) eq $hash)
{#User authenticated.
  my $session = new CGI::Session("driver:File",undef,{'Directory'=>"/tmp/FBSess"});
  $session->param('user',$un);
  $session->expire('+1M');
  $id = $session->id();
  $host = $ENV{'HTTP_HOST'};
  print "Set-Cookie: session=$id; domain=$host; path=/\n\n";
}


This returned into $entry the /etc/passwd entry from paprika for me to then parse and authenticate against.

If the user supplied correct login information, I used CGI::Session to create a session for the user. The server keeps the sessions in /tmp/FBSess directory in the filesystem. Then I set a cookie on the user's browser that contains the session ID. When the user hits the server with the cookie, the session ID is looked up in /tmp/FBSess and the user's session information is available to the server. Now that they are authenticated and the server knows who the person using the browser is, they can browse under their own identity.

When the user is done browsing, they can then logout. This sets the cookie to expire at the end of the browsing session and deleted the session on the server side. The next user using the browser cannot then browser under the previous users name.

List View (Sam)

A smaller, but still difficult, feature of the project was the list view. We did this by switching between two different CSS files. The difficult part was not the JavaScript to switch CSS files, but the CSS itself. The text was not lining up with icons correctly, and the columns of information were not lining up. Also, the files were being indented, each one more than the previous. We finally resolved this issue, and it was mostly a matter of tinkering with the CSS. The main problem was that the icons where taller than the text, so the next file was being pushed out of the way. This was a small problem, but one that still took a lot of headache to work out.

Tooltips (Elliott)

Getting the tooltips to work was the bane of my existence during the middle of our project. After we refractored our code the first thing we worked on was getting tooltips to show information about each file when hovered over. After trying several tooltips that were very strict and not at all dynamic, we finally came across the one we are currently using which gave us flexibility to create tooltips and populate their divs on the fly . Unfortunately, this broke the drag and drop function as the javascript engine couldn't handle rendering the tooltip as it was moving from the drag and drop. We were able to scrape some functions together for our next presentation, but the result was not ideal.

To fix the problem, we had to destroy the tooltips and the divs the tooltips were in on the mousedown event for each icon and then create and populate them again on the mouse up. This proved to work for our presentation, but as each tooltip was created by a single request, there was a lot of server traffic which caused some errors. Sometimes the requests would not come back in the order in which we called them or another request, to load or refresh the directory, would be made in the middle of setting the tooltips. This overlapping would try to create and destroy the tooltips at the same time and would break our page. It took us a long time to realize this was happening.

We could not simply leave the tooltips divs intact, or the page would not update and the tooltip would remain visible until the next mouseover event was called and double clicking the folder somehow permanently left the tooltip frozen in it's place. We decided to hide the tooltip divs rather than destroy them. This kept them out of view when an icon was clicked, and also reduced the server traffic for recalculating all the tooltips after every click on the page.