Understanding Permissions for Various APIs in Open Event API Server

Since the Open Event Server has various elements, a proper permissions system is essential. This huge list of permissions is well compiled in the developer handbook which can be found here. In this blogpost, permissions listed in the developer handbook are discussed. Let’s start with what we wish to achieve, that is, how to make sense of these permissions and where does each clause fit in the API Server’s codebase.

For example, Sponsors API has the following permissions.

List

View

Create

Update

Delete

Superadmin/admin

Event organizer

✓ [1]

✓ [1]

✓ [1]

✓ [1]

✓ [1]

Registered User

✓ [3]

✓ [3]

✓ [4]

✓ [3]

✓ [3]

Everyone else

✓ [2][4]

✓ [2][4]

  1. Only self-owned events
  2. Only sessions with state approved or accepted
  3. Only self-submitted sessions
  4. Only to events with state published.

Based on flask-rest-jsonapi resource manager, we get list create under ResourceList through ResourceList’s GET and POST methods, whereas View, Update, Delete work on single objects and hence are provided by ResourceDetail’s GET, PATCH and DELETE respectively. Each function of the permission manager has a jwt_required decorator.

@jwt_required
def is_super_admin(view, view_args, view_kwargs, *args, **kwargs):

@jwt_required
def is_session_self_submitted(view, view_args, view_kwargs, *args, **kwargs):


This
 ensures that whenever a check for access control is made to the permission manager, the user is signed in to Open Event. Additionally, the permissions are written in a hierarchical way such that for every permission, first the useris checked for admin or super admin, then for other accesses. Similar hierarchy is kept for organizer accesses like track organizer, registrar, staff or organizer and coorganizer.

Some APIs resources require no authentication for List. To do this we need to add a check for Authentication token in the headers. Since each of the functions of permission manager have jwt_required as decorator, it is important to checkfor the presence of JWT token in request headers, because we can proceed to check for specific permissions in that case only.

if 'Authorizationin request.headers:
 _jwt_required(current_app.config['JWT_DEFAULT_REALM'])


Since the resources are created by endpoints of the form : 
‘/v1/<resource>/` , this is derived from the separate ResourceListPost class. This class is POST only and has a before_create object method where the required relationships and permissions are checked before inserting the data in the tables. In the before_create method, let’s say that event is a required relationship, which will be defined by the ResourceRelationRequired , then we use our custom method

def require_relationship(resource_list, data):
    for resource in resource_list:
        if resource not in data:
            raise UnprocessableEntity({'pointer': '/data/relationships/{}'.format(resource)},
                                      "A valid relationship with {} resource is required".format(resource))


to check if the required relationships are present in the data. The event_id here can also be used to check for organizer or co-organizer access in the permissions manager for a particular event.

Here’s another permissions structure for a different API – Settings.

List

View

Create

Update

Delete

Superadmin/admin

Everyone else

✓ [1]

  1. Only app_nametaglineanalytics_keystripe_publishable_keygoogle_urlgithub_urltwitter_urlsupport_urlfacebook_urlyoutube_urlandroid_app_urlweb_app_url fields .

This API does not allow access to the complete object, but to only some fields which are listed above. The complete details can be checked here.

Resources

Continue ReadingUnderstanding Permissions for Various APIs in Open Event API Server