Skip to content

Profile Details and Roles

Developer From Jokela edited this page Sep 17, 2022 · 2 revisions

To begin interfacing with Wilma, we need to get a JSON response from https://<wilmaurl>/api/v1/accounts/me to check if user has MFA enabled

Successful response with HTTP response code 200:

{
   "statusCode":200,
   "payload":{
      "id":56,
      "firstname":"Testi",
      "lastname":"Testaaja",
      "username":"testi.testaaja",
      "lastLogin":"2022-09-14 09:17",
      "sessions":[],
      "multiFactorAuthentication":false
   }
}

If response code is 403, without any errors in the response, account is an old type account.


In order to get user's

  • name
  • type
  • id
  • school
  • formkey

We need to get a JSON response from https://<wilmaurl>/api/v1/accounts/me/roles

Successful response:

{
  "statusCode":200,
  "payload":[
    {
      "name":" Testi Testaaja",
      "type":"passwd",
      "primusId":56,
      "formKey":"passwd:56:df15a7dec0f0e75190e4cb1ba343d271",
      "slug":"",
      "schools":[

      ]
    },
    {
      "name":"Titta Tapola",
      "type":"student",
      "primusId":4291,
      "formKey":"student:4291:df15a7dec0f0e75190e4cb1ba343d271",
      "slug":"\/!024291",
      "schools":[
        {
          "id":12,
          "caption":"Esimerkkilän peruskoulu (0-9)",
          "features":[
            "school_common"
          ]
        }
      ]
    },
    {
      "name":"Heikki Hypoteesi",
      "type":"teacher",
      "primusId":118,
      "formKey":"teacher:118:df15a7dec0f0e75190e4cb1ba343d271",
      "slug":"\/!01118",
      "schools":[
        {
          "id":12,
          "caption":"Esimerkkilän peruskoulu (0-9)",
          "features":[
            "school_common"
          ]
        }
      ]
    },
    {
      "name":"Titta Tapola",
      "type":"guardian",
      "primusId":4291,
      "formKey":"guardian:4291:df15a7dec0f0e75190e4cb1ba343d271",
      "slug":"\/!044291",
      "schools":[
        {
          "id":12,
          "caption":"Esimerkkilän peruskoulu (0-9)",
          "features":[
            "school_common"
          ]
        }
      ]
    }
  ]
}

ID and user type:

User ID is contained in primusId field, and user type is in type field of each role.

formkey field is important and should be stored for further requests. Value is a custom implementation which resembles CSRF token's functionality, except every role has its own token and they refresh on every session, rather than on every request.

formkey's value typically has this kind of structure: usertype:userid:random_value

Here's a list what each value means (list is still incomplete, as we haven't discovered all used type strings in Wilma):

  • teacher: Teacher
  • student: Student
  • personnel: School personnel
  • guardian: Parent of the student
  • workplaceinstructor: Workplace instructor
  • board: Management
  • passwd: Wilma Account (this type means that account has to choose a role before continuing, for example if the account's type is guardian with multiple students "owned" by it)
  • trainingcoordinator
  • training
  • applicant
  • applicantguardian

Handling roles

There are two types of accounts in Wilma

  • Without roles (old account type)
  • With roles (new account type)

We can already determine account types by calling /api/v1/accounts/me.

In addition to that, you can differenciate account types by going through all roles in the JSON response.

If:

  • roles array contains a role with account type passwd and its slug field is empty -> New type, needs role handling
  • contains one role, slug field is empty -> Old type account, no need for role handling

How to handle roles with new account type

Your implementation should prompt end user to select the role.

Your HTTP client should append slug parameter from active role to Wilma server's URL address.

Example: https://wilmadomain/!044291

Notice! In further POST requests role's formkey should be used when slug is appended to the URL!

What about old account types?

Old account types needs no additional handling.

Clone this wiki locally