Statistics
| Branch: | Tag: | Revision:

root / docs / source / webclient.rst @ 50f4d97e

History | View | Annotate | Download (14.6 kB)

1
Pithos+ Web Client
2
==================
3

    
4
Introduction
5
------------
6
The Pithos+ Web client documentation contains information about installation and configuration of the web client along with information about the development of the client (development environment, tools, libraries, API usage etc).
7

    
8
Build instructions
9
------------------
10
Prerequisites: git, jdk 1.6, ant
11

    
12
First get the source from the git repository
13

    
14
git clone https://code.grnet.gr/git/pithos-web-client
15

    
16
Enter the newly created folder
17

    
18
cd pithos-web-client
19

    
20
and run ant
21

    
22
ant
23

    
24
Now go to the output folder
25

    
26
cd bin/www/gr.grnet.pithos.web.Pithos
27

    
28
This folder contains the "binaries" (html and javascript actually). Those files should be put somewhere to be served by the web server.
29
For deploying to pithos.dev.grnet.gr, upload everything to /var/www/pithos_web_client where they are served under /ui.
30

    
31
Important reminder: Due to Same-Origin-Policy the web client should be served under the same domain as the API.
32

    
33
Configuration
34
-------------
35

    
36
All configuration exists as javascript variables in index.html file. The things that need to be configured are:
37

    
38
loginUrl: The url that the client will redirect the user if she is not logged in (defailt: /im/login?next=). The next= parameter is determined automatically.
39

    
40
authCookie: The name of the authentication cookie that is set by the login process which is external to the web client (default: _pithos2_a).
41

    
42
feedbackUrl: The url that the client should use to POST feedback messages from the user when an error occurs (default: /im/feedback).
43

    
44
The CLOUDBAR_* set of variables is related to the bar that is displayed on the top of the web client 's page. This bar is used to navigate to other services of the cloud and also contains a menu for sendind feedback, inviting other people, logout etc. This bar is also externally configured and the web client just loads it as a script.
45

    
46
CLOUDBAR_ACTIVE_SERVICE: The service that we currently see (in case of the web client it is always pithos).
47

    
48
CLOUDBAR_LOCATION: The url that tha cloudbar script is loaded from (default: /static/im/cloudbar/).
49

    
50
CLOUDBAR_SERVICES: The url that is used to get the available service (default: /im/get_services).
51

    
52
CLOUDBAR_MENU: The url that the menu is loaded from (default: /im/get_menu).
53

    
54
Development environment
55
-----------------------
56
The development environment used is Eclipse Indigo with the Google Plugin for Eclipse but other environments can be used without problems. The libraries needed for development is
57

    
58
Google Web Toolkit (GWT) v.2.4.0 (http://developers.google.com/web-toolkit/)
59

    
60
The gwt-user.jar is needed in the classpath in order to compile the source. The gwt-dev.jar is needed to run the development mode server for debugging.
61

    
62
All dependencies are downloaded automatically by the ant build script (build.xml) in the dependencies folder if not already found there.
63

    
64
Building
65
^^^^^^^^
66
Building the project consists just of compiling the java source into javascript and html by the GWT compiler. This is done by the ant script (ant target "gwt-compile")
67

    
68
Debugging
69
^^^^^^^^^
70
Debugging is done using the GWT development server. The ant script has a special target (run-web-dev-mode) which starts the devmode server, but one can do the same thing from inside Eclipse. In order to use the devmode server, the GWT plugin is needed in the browser. This way the browser communicates with the devmode server and the developer can set breakpoints, examine variable values, evaluate expressions etc for the application that runs in the browser.
71

    
72
Technology and tools
73
--------------------
74
Pithos+ web client is a gwt application. It is written in Java and compiled to javascript that runs in the browser. More info about gwt can be found here http://developers.google.com/web-toolkit/
75

    
76
General architecture
77
--------------------
78

    
79
The web client does an adaptation of the container/object server-side data model to the more user-friendly folder/file data model. The client uses the API to retrieve info about the containers and objects from the server and displays them in a tree-like structure. It uses two special gwt widgets, CellTree (https://developers.google.com/web-toolkit/doc/latest/DevGuideUiCellWidgets#celltree) and CellTable (https://developers.google.com/web-toolkit/doc/latest/DevGuideUiCellTable) for the folder tree and filelist accordingly. The CellTree widget initiates calls to the API at the beginning and each time a subtree is expanded in order to fetch all info needed to display the subfolders. That way the datamodel is controlled by the widget.
80

    
81
Source code structure
82
---------------------
83
Java source code consists of the following packages:
84

    
85
gr.grnet.pithos.web.client: This is the root packages that containes the Pithos class which is the application entry point and various utility classes like menus, dialogs etc.
86

    
87
gr.grnet.pithos.web.client.foldertree: All classes related to the datamodel and tree widget that displays containers, folders and files.
88

    
89
gr.grnet.pithos.web.client.mysharedtree: All classes related to the datamodel and tree widget that displays the objects shared by me.
90

    
91
gr.grnet.pithos.web.client.othershared: All classes related to the datamodel and tree widget that displays the objects shared to me by other users
92

    
93
gr.grnet.pithos.web.client.grouptree: All classes related to the datamodel and tree widget that displays the groups and users used by the user in order to share files to groups of people more easily.
94

    
95
gr.grnet.pithos.web.client.commands: This packages contains the commands issued by the various menus (right-click menus and toolbar).
96

    
97
gr.grnet.pithos.web.client.rest: This package contains the classes that define the HTTP requests made to the API
98

    
99
gr.grnet.pithos.resources: This folder contains various images used as icons in the application 's UI. Those images are embeded in the javascript code by the GWT compiler for efficiency and therefore they are not served as static files.
100

    
101
gr.grnet.pithos.web.public: This folder contains the index.html page of the application and all related css and other files loaded by it (like the plupload scripts for multiple file uploading).
102

    
103
Authentication
104
--------------
105

    
106
Authentication is provided by an external service. Upon loading,, the web client checks for the existence of the authentication cookie named '_pithos2_a'. If the cookie is present then it is parsed for the username and authentication token. The format of the cookie content is
107

    
108
username|token
109

    
110
These username and token are used for every request to the server. If at any time, the client receives an HTTP 401 (Unauthorized) which means that the token has expired, then the user is informed and redirected to the login page.
111

    
112
If the auth cookie is not present in the first place then the user is immediately redirected to the login page.
113

    
114
The login page url is defined in the index.html file and it must end with a 'next=' url parameter. The value of the parameter will be determined automatically. If the parameter is not present then the login page will not be able to redirect back to the client after a successful login and the user will end up at her profile page.
115

    
116
API Usage
117
---------
118

    
119
Initialization
120
^^^^^^^^^^^^^^
121
Upon loading, the web client performs the following steps:
122

    
123
Ckeck if the user is authenticated (auth cookie present)
124

    
125
The application page is constructed
126

    
127
Requests the server for the user account and files. This is done in various stages. First a request is made for the user account data
128

    
129
GET /v1/username?format=json
130

    
131
If there is a container named 'pithos' and a container named 'trash' then it proceeds to the folder tree construction. Otherwise the missing containers will be created with requests
132

    
133
PUT /v1/username/pithos
134

    
135
PUT /v1/username/trash
136

    
137
Constructing the folder tree
138
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
139
The folder tree displays in a tree structure all the user 's containers (including trash). For each container a request is made
140

    
141
GET /v1/username/pithos?format=json&delimiter=/&prefix=
142

    
143
to get the first level of folders (either actual objects with application/folder content type or virtual prefixes). The home folder (pithos) is always displayed first, selected and expanded and the trash container is always last.
144

    
145
Due to the pithos container being programmatically selected and expanded at the beginning, additional requests 
146

    
147
GET /v1/username/pithos?format=json&delimiter=/&prefix=pithos_subfolder1
148

    
149
are made to the server to fetch details of the subfolders. We need to know if a subfolder has its own subfolders so that we display the cross sign next to it.
150

    
151
Constructing the "Shared by me" tree
152
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
153
My shared tree construction is a bit more complicated. All files that are shared individualy (not through sharing their parent folder) are displayed directly in the root of the tree (inside the 'Shared by me' folder).
154

    
155
All shared folders are displayed in tree structure under the root.
156

    
157
The above means that the client has to make a series of requests to collect all shared items and display them accordingly.
158

    
159
First a
160

    
161
GET /v1/username/container?format=json&delimiter=/&prefix=
162

    
163
is made for each container. If the container is shared it is added to the tree (under "Shared by me") and the client continues to the next container (this has to be re-visited because it was based on the fact that due to the permission inheritance the subfolders are also shared. Since the inheritance has been removed this is no longer valid).
164

    
165
If the container is not shared we have to go deeper to find possible shared subfolders and files. So we examine each file in the folder and if shared we add it in the "Shared by me" folder and we also do a nested iteration getting each subfolder
166

    
167
GET /v1/username/container?format=json&delimiter=/&prefix=subfolder
168

    
169
and this is done recursively until all shared folders have been collected.
170

    
171
Constructing the "Shared to me" tree
172
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
173
The "Shared by others" tree has the additional complication that we need to get the users that share objects with us and display them as a first level of subfolders.
174

    
175
GET /v1?format=json
176

    
177
For each of the users we do an additional
178

    
179
GET /v1/username?format=json
180

    
181
to get the containers shared by the user and for each container we do the same sequence of requests as in the "Shared by me" case. The difference here is that we don't need to check if the container/folder/file is shared because all requests with a different username always return only objects that are visible to the logged-on user.
182

    
183
Constructing the Groups tree
184
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
185

    
186
The groups tree is contructed with the initial request for the user account data which returns the groups defined by the user along with their members.
187

    
188
Functionality
189
-------------
190
The web client provides functionality which is typical to a file manager like copy/cut/paste of individual files, create/rename/delete of folders, upload/rename/delete files etc. All such operations are done by using single calls to the API or combination of calls.
191

    
192
Folder operations
193
^^^^^^^^^^^^^^^^^
194
Folder creation
195
"""""""""""""""
196
is done by the FolderPropertiesDialog class with a request
197

    
198
PUT /v1/username/container/path/to/new/folder
199

    
200
Folder removal
201
""""""""""""""
202
is done by the DeleteFolderDialog class and is a bit more complicated because the files and subfolders must be deleted first. A request
203

    
204
GET /v1/username/container?format=json&delimiter=/&prefix=/path/to/folder
205

    
206
is made to retrieve all objects with names starting with the folder 's prefix. All objects are deleted with requests
207

    
208
DELETE /v1/username/container/path/to/folder/file
209

    
210
and if any of those objects is a marker object (folder) itself the same procedure is followed recursively. Finally a 
211

    
212
DELETE /v1/username/container/path/to/folder
213

    
214
is made to delete the initial folder.
215

    
216
Folder rename
217
"""""""""""""
218
is done by a 
219

    
220
PUT /v1/username/container/path/to/new/foldername
221

    
222
to create a folder with the new name, followed by recursive copy operations (see below about copy/move/paste) to move all folder 's children under the new one. Finally, a folder deletion is done as described earlier.
223

    
224
File Cut/Copy/Paste
225
"""""""""""""""""""
226
Cut/Copy operations on folders just put the objects in an internal clipboard. The Paste command does the actual job of copying/moving.
227

    
228
Folder copy is done by creating a folder at the new location with a PUT and then recursively copy all subfolders and files.
229
Folder move is done the same way followed by a deletion of the initial folder. It is obvious that a copy/move of a big subtree will result in a great number of API requests.
230

    
231
File Operations
232
^^^^^^^^^^^^^^^
233
File uploading
234
""""""""""""""
235
File uploading is done using the plupload http://www.plupload.com/ plugin. The plugin supports multiple file upload, drag'n'drop from the desktop and progress indication. It uses any of the following technolgies (whatever is available in the browser) html5, flash, gears, silverlight, browserplus, html4 in this order. If none is found then html4 is the last fallback in which case most features are not available (no drag'n'drop, no progress indicator).
236

    
237
The upload operation is done with a 
238

    
239
POST /v1/username/container/path/to/file?X-Auth-Token=<auth token>. This is the only case the auth token is passed as a url parameter. The reason is that it cannot be passed as a header due to the fact that the POST is not controlled by the code, it cannot be passed as POST payload parameter (form parameter) for efficiency reasons (the server should read the whole file first, before reading the token) and it cannot be passed as a cookie to avoid XSRF attacks.
240

    
241
File rename
242
"""""""""""
243
is done by FilePropertiesDialog class with a
244

    
245
PUT /v1/username/container/path/to/newfilename
246

    
247
with X-Move-From header containing the old path.
248

    
249
File delete
250
"""""""""""
251
is done by DeleteFileDialog class with a simple
252

    
253
DELETE /v1/username/container/path/to/file
254

    
255
File Cut/Copy/Paste
256
"""""""""""""""""""
257
Cut/Copy operations on files just put the objects in an internal clipboard. The Paste command does the actual job of copying/moving.
258

    
259
In case of copy, a sequence (if multiple files are copied) of PUT commands is issued to the new path, with X-Copy-From header
260
In case of cut, the same PUT commands have X-Move-From header set.
261

    
262
File/Folder sharing
263
^^^^^^^^^^^^^^^^^^^
264
Sharing of file and folders with other users is done by setting permissions for other users or groups of users. The FolderPermissionsDialog/FilePermissionsDialog classes display the corresponding UI and perform the API calls. Permissions are set with
265

    
266
POST /v1/username/container/path/to/object
267

    
268
with the X-Object-Sharing containing the permissions (see Pithos+ development guide).
269

    
270
In the case of a virtual folder (no marker object) the above operation will return 404 (Not Found) and a PUT request is needed to create the marker and then repeat the POST.