commented .. meta:: :http-equiv=refresh: 5
Web API¶
Warning
Ultimately this file should become redundant and the actual documentation of the flask routes should take over
Following set of slides is a very good Link read before discussing this
This application would have a combination of REST and RPC calls. Or maybe rest like calls with few posts involving methods. Using celery to exececute server side operations it is more logical to use rpc like posts on resources pointed by REST api.
References for securing web API’s
- Implement in a blueprint so that the url-prefix makes it identifies diferent versions
- Do some validation in every request, i.e. determine if the user is logged in and what can be queried and then use common helper python routines to get and serve the data
Rest API v1¶
important
All the queries in version 1 are prefixed by apiv1
i.e. to get a list of databases -
localhost:8080/apiv1/databases
Rest API blueprint is established and later consumed in the web templates interface.
Two kinds API for two kinds of database types. those in image database, and those in administrative database. Those in image database require a database id (to locate the database) in each request.
A common decorator to check the access @security.login_required, and @site_admin required implemented so far.
Put requests are used for putting entities e.g. file where the destination is known. POST requests are used for posting new resources, in particular complete objects. When partial modifications are to be made, PATCH command is used..
TODO: there should be a common place for access information computation about the sessions. This will improve the performance of the each reqeust.
Sessions¶
A session is smallest unit for which an access can be granted or revoked. It contains lists of useful items like
- Raw images (that are to be processed internally)
- Views of images
- Downloadable file attachments, that are simply stored.
A list of sessions in a known databaseid is obtained by -
GET /apiv1/<dbid>/sessions
The main use case of this list is to display selectable sessions with the access rights to the user that is logged in So the view, attachments and etc lists are not included.
Warning
TODO: It is not very convenient to get session list in this format, as the list should include all the sessions (regardless of the database) visible to the user. Possible grouped by the “facebook group” or the “rule” that granted the access.
New sessions can be posted here
POST /apiv1/<dbid>/sesisons
{ 'insert: { 'label' : "label string }}
returns the newly inserted session object with empty views and attachments lists
A particular session is obtained by
GET /apiv1/<dbid>/sessions/<sessid>
The main use case of this is to present the session to the user. So this does contain all the lists. Views, attachments and rawfiles etc are dereferenced to include enough details to present them in a list.
or is deleted by
DELETE /apiv1/<dbid>/sessions/<sessid>
Warning
This call presently works only if the session i.e. the lists of items in it are completely empty. If an attempt is made to delete a non-empty session, an error will be returned. This will change when management of orphan items is implemented.
It might be useful to have an api call to purge entire session including all the items (images / files or attachments) in a session.
POST /apiv1/<dbid>/sessions/<sessid>
{purge : [ <"session", "images", "attachments", "raw-files">] }
- The parameters can be “session”, in which case all the items are recursively removed along with the session.
- Other parameters will delete all the items of a kind. i.e. “images” will delete all the images.
Note
Another possibility is to move all the items to an orphan session which is displayed only to administrators.
Modifying the properties of the session are made possible by
POST /apiv1/<dbid>/sesisons/<sessid>
{ 'modify' : { 'label' : "label string }}
Items in session (Attachments / Views)¶
A list of the items can be obtaied by
GET /<dbid>/sessions/<sessid>/attachments
GET /<dbid>/sessions/<sessid>/views
GET /<dbid>/sessions/<sessid>/rawfiles
Later can be generalized to any list
GET /<dbid>/sessions/<sessid>/<resource-type>
To get or delete items
DELETE /<dbid>/sessions/<sessid>/attachments/<attachid>
DELETE /<dbid>/sessions/<sessid>/views/<viewid>
DELETE /<dbid>/sessions/<sessid>/rawfiles/<fileid>
Uploading attachments or raw files, first a POST request should be made make a post request to get a new _id, and then upload the file to that _id. That _id will be the _id in gridfs
POST /apiv1/<dbid>/sessions/attachments
{ "insert" : {} }
On success returns
{ "_id" : <string ObjectId>}
Warning
The ObjectId is not actually inserted in the attachements collection until the file is actually uploaded. So it will not be visible as attachment or rawfile until then
On success returns
{'_id' : <ObjectId>}
So in the following request And in the following PUT request(s) file chunks are uploaded. see the code for details
PUT /apiv1/<dbid>/sessions/attachments/<fileid>
{'_id' : <ObjectId>}
TODO: API and UI for insering views is being designed
Items can be modified directly or indirectly for example renaming
PATCH /apiv1/<dbid>/sessions/<sessid>/attachments/<attachmentid>
{ 'label' : "NEW_NAME"}
PATCH /apiv1/<dbid>/sessions/<sessid>/views/<viewid>
{ 'label' : "NEW_NAME"}
TODO: Implement above patch queries
Operations like reordering also involve post query
PATCH /apiv1/<dbid>/sessions/<sessid>/views/<viewid>
{ 'label' : "NEW_NAME"}
returns
{ 'label' : "NEW_NAME"}
Or in rare cases when position value of all elements needs to be changed in the client side, it returns entire list
Administrative database¶
- Resources for administrative interface are “database”, “rule”, “user”
- Since the final destination {_id} of the resource is not known to calling rest API POST operation is used
- All queries return empty list when used with GET or 403
- Resources will return 40X depending on the error
- There could be a generic API for
Administrative access is required to any queries dealing directly with administrative database
- GET
- /apiv1/databases/<databaseid>
- /apiv1/databases?dbname=<databasename>
- /apiv1/rules?facebook_group=<facebookid>
- /apiv1/rules/<ruleid>
API for access grant / revole take 2¶
- GET
- /apiv1/roles
- /apiv1/roles/<roleid>
To Grant / Revoke¶
API Grant operation involves
- Permission (can_admin, db_admin, can_see, site_admin)
- Target resource
- Target UserRole / GroupRole
Getting Roles¶
Users see rules for only targets for which they have admin access.
For a user¶
The user himself, level 0
- GET
/apiv1/users/<userid>/roles
Role = {"id" : "id", "label" : "label"}
return { "userRole" : Role, "grouproles" : [ Roles ] }
For a resource¶
Level 3 or lower privilege users see the rules which belong to sessions they can administer.
- GET
/apiv1/<dbid>/sessions/<sessid>/roles
Role = {"id" : "id", "label" : "label"}
return { "userRoles" : Role, "groupRoles" : [ Roles ] }
Adding or removing a user to a group¶
If the user has administrative rights for all the content mentioned in RoleGroup, then that user can remove users from the role.
- POST
/apiv1/users/<userid>/roles
{ "grant" | "revoke" : <roleid> }
Create a new Role¶
When applying permission to an existing single target
The requesting user should have administrative rights for all the content mentioned in permission.
GET : /apiv1/roles/roleid
{ "permissions" [ "arrayofpermissions", ] }
"operation" : ["grant" | "revoke"]
}
This endpoint should cover users and rules both.
Modifying the permissions¶
The requesting user should have administrative rights for all the content mentioned in permission.
-PATCH / PUT
/apiv1/roles/roleid
/apiv1/roles/roleid
{ "permissions" [ "arrayofpermissions", ] }
"operation" : ["grant" | "revoke"]
}
This endpoint should cover users and rules both.
For granting new permissions to multiple users, or to a new group
- POST
/apiv1/roles
{
"users" : [ <userid> , .. ],
"create_group": {
#if a group is to be created then
#provide group properties
"label" : "somelabel"
}
"permissions" [ "arrayofpermissions", ]
}
return Response({ "users" : {"userid" : "roleid"} | "group" : "roleid" }, 201)
Depending on the type, for userRole, permissions are applied
To modify a role¶
- POST
/apiv1/roles/<roleid>
{ partial list of fields to modify, perhals push to permissions "grant" | "revoke" : <roleid> }
{ "target" : [ "user" | "group" ],
"to" : [ "_id", ], ,
"type" : ["allow" | "deny"],
"permission" : { "dbid" : "_permission_object_",
"can_see" : [ "a" ] }
}
Warning
Anything below this is not edited
Get all the users to which given rule is applied
- GET
- /apiv1/rules/<ruleid>/users
Apply / Revoke the access the rule users to which given rule is applied
- POST
- /apiv1/rules/<ruleid>/users
{"grant" : <userid> }
- /apiv1/rules/<ruleid>/users
{"revoke" : <userid> }
- Add new rule or database or user
- POST /apiv1/databases
{ 'insert' : {'label' : <label>, 'dbname' : <dbname>, 'host' : <host>}}
- POST /apiv1/rules
{ 'insert' : {'label' : <label>, 'dbid' : <dbid>, 'can_see' : [ <sessid>, .. ], 'db_admin' : <truefalse> .. etc}}
A custom validate method over generic object schema checking
- Whether the database with that dbname exists (and is it slideatlas database)
- Whether the rule exists
- validity is checked before applying the rules
To fully replace a known database record
- PUT /apiv1/databases/<dbid>
{ '_id' : <id>, 'label' : <label>, 'dbname' : <dbname>, 'host' : <host>}
To partially or fully modify a known database record
- POST /apiv1/databases/<dbid>
{ 'insert' : { '_id' : <id>, 'label' : <label>, 'dbname' : <dbname>, 'host' : <host>}}
operations for specific users, a deep delete to also remove all the rules associated with the user
- DELETE
High level API to manage access rights¶
Get a list of registered facebook groups
GET /apiv1/facebook-groups
The use cases include -
TODO: In future, the groups can be superset of facebook group
Warning
How to make sure that while modifying the access rules, minimum rule records are created. For example, when User1 has can_see permission to SessionA, and a second request comes to grant User1 permissions to User2, will it be possible to reuse the rule. What if on a later day, the permission is revoked only for User1. Then User2 has can_see permission to SessionA. Then rule can be removed from User1’s rules. But if the rule contains SessionA and SessionB then a new Rule needs to be created for User1 for only access to SessionB as access to SessionA has been revoked.
- Manipulate the permissions of a facebook group. i.e. grant or revoke
GET /apiv1/facebook-groups
POST /apiv1/facebook-groups/<facebook-group-id>
{'dbid' : '<dbid>', can_see' : [ '<sessionid>', ... ]}
{'dbid' : '<dbid>', 'can_see_all' : [ '<sessionid>', ... ]}
Authentication (login) operations¶
- A user session can be created by either sending an json request or by logging into page which sends out a json request to the api.
TODO: Rewrite this documentation in the light of new API
- / Home page
- login form
- Information on what this site is about
- / login
- &type=google
- &type=facebook
- &type=openid
- &type=password
Few access rights are calculated at the time of login. Hence if the access rights are calculated while the user is logged in the user must logout and login again to see the effect.
Viewing and other pages¶
Main image view with annotation management
- /glviewer/<viewid>
- ?viewid=<viewid>
- &dbid = <dbid>
/olviewer?viewid=<viewid> - ?viewid=<viewid> - &dbid = <dbid>
TODO: Probably the img appears only in one database, and so dbid could be resolved internally / stored in viewid