Implement permission model

Issue #120 closed
Brian Lewis repo owner created an issue

Desktop Pineapples uses a granular permissions architecture that divides the application into topics, and assigns rights to the user in that topic.

Topics include :

  • school;
  • teacher;
  • establishment;
  • enrolment;
  • survey;
  • finance;
  • infrastructure;

etc

Rights are :

  • Read : may read topic data
  • ReadX: may read extended topic data
  • Write: may write basic topic data
  • WriteX: may write extended topic data
  • Admin: may administer data in this topic; for example manage lookup lists
  • Ops: may perform any specific data manipulation operations in this topic.

Some rights imply others:

ReadX => Read WriteX=>ReadX WriteX=> Write

In the Pineapples database each Topic/Role is represented as a Role; eg pEstablishmentRead . These roles are called Functional Roles.

The user (logged in to the database using Windows Authentication) belongs to a role representing their user group e.g. FinanceOffice. the roles are called Organisational Roles.

Each Organisational Roles is a member of a set of Functional Roles. these membership bestow database permissions on the logged in user.

However, the database connection from the web site is made in the name of the service account running the web site, so this model cannot work. (Using impersonation limits scalability because database connections cannot be reused. ) So we need to enforce the user privileges in other ways.

At the server the user must be prevented from connecting to any api endpoint to which they do not have permission (e.g. cannot edit a school record if not assigned to pSchoolWrite ).

On the client, the user interface should reflect operations that the user s not permitted to perform (e,g. the edit button in the School Item form is only available if the user is in pSchoolWrite) .

Note that client side permission are treated as a "courtesy", to allow the user to understand their role, and not perform operations that will fail due to authorization restrcitions at the server. All authorization is enforced on the server.

Implementing Authorization as Claims

These granular permissions will be determined at login time, and encoded as claims in the bearer token. When an api endpoint is called, authorization is determined by interrogating the claims in the current ClaimsIdentity.

Further, the permissions information is sent to the client at login time, along with the token. This enables the client-side code to access this information when configuring the Ui.

To keep the data small, (mindful of the overhead in including information in the bearer token) the permissions will be hashed into a short string:

Each character of the string will represent a topic. Since their are 6 possible rights for each topic, there are 64 possible values for the topic 0 - 63 ( noting that the dependencies between rights mean that in actuality, many of these combinations cannot be used). Adding 48 to this value produces a displayable character in the range 48-111. This is the character included in the string to represent that topic. In this way, the permission grid is rendered as an 11 character string.

Server-side Implementation

An attribute PineapplesPermission(topic, right) may be assigned to any Api endpoint (ie api controller method) to enforce that permission on the endpoint.

Client-side Implementation

Is based on angular-permission , creating a permission named p<topic><right>

e.g.

<span permission permission-only="pSchoolWrite">Click to edit...</span>

Assigning Permissions

For AspIdentity authentications, permissions will be assigned directy into AspUserClaims table. The hashed string will be stored as the claim value.

For AD authentications, we will map the user to a "proxy" in AspNetUsers in identity. This proxy will be determined by the group memberships of the user. The permission claim will be associated to this proxy.

e.g. a user that is a member of AD group ScholarAdmins may be assigned to a proxy AspNetUser account of the same name. The account will have a permission claim corresponding to the rights assigned to this group.

Comments (2)

  1. Ghislain Hachey

    This was implemented right? Further work would be fixes feature updates? We could close this issue and create new smaller ones as needed.

  2. Log in to comment