Retrieving roles array of user

Dear community

How am I able to get all the roles that the logged-in user has?
I tried it with the following line in the xlsxForm, but I never get any results.

@diana or @mrjones would any of you maybe be able to answer my question above? >< I’d highly appreciate it.

Thank you very much in advance for your help
Bests,
Ünsal

Hi Ünsal, sorry for the slow response over the holidays. I haven’t had a chance to test this hypothesis out, but it is possible that you can’t directly assign the role array to a string. Have you tried assigning it to a different field type, such as a repeat group to get the inner value(s) that way? That may work, and if not perhaps someone else has encountered this situation before and could offer advice.

Hi @uensal

Currently, I don’t think there is no way to access user roles in forms. You do, however, have access to the user’s associated contact.

We had a similar request some time ago, that resulted in adding an API to verify the permissions of the logged in user - this new api is available in tasks, targets and contact-summary, and will be available in the purge function in the future (this improvement is already scheduled). For more details, please check this issue: Ability to access "user permissions" from tasks, targets, and contact-summary · Issue #6914 · medic/cht-core · GitHub

We could make this available in forms by adding another xpath extension function for the APIs (details about CHT xPath functions: app | Community Health Toolkit).

2 Likes

Hi @diana and @marc

Thank you for your responses.
I am currently not working anymore for the project and have already handed it over to my successor. If he wants to follow up on this, I think he will come forward and continue here.

Nevertheless, thank you very much for your support.
Bests,
Ünsal

Hi,
How could I access user’s associated contact in a contact form ? I’ve tried with a group contact into the user group but it doesn’t work for me, is the correct way ?

Hi @bamatic, sorry for the late reply.

As you can see in the default config contact forms, we can get contact_id from the user group.
image

This is the UUID of the associated contact document of the current user.
We can use this UUID to pull other information stored in the contact document such as name, role, and date_of_birth.

Here, we are using a CHT XForm widget: select-contact. For v3.9.0 and below, we need to set the appearance to db-object instead of select-contact.

The contact form will look like this:
image

1 Like

Dear @binod,
Amazing what is all possible.
For me this is not working. When I check directy in the database, there is no role entry for Persons, only for user and there it is not role but roles.
Still it is not working for me, that field seems not to load anything.

Do you by chance have an explanation how the input and init groups actually work, so that implementers can do this on their own?
Why do you have to add a calculate field for contact_uuid that just copies the content of the field contact_id, a field that can already be used in note and other fields.

Why do you have to write ../role when role is in your level and not in the parent level? Why is it not just ./role

I just want to have the user role of the current user in the form, but no matter how I do it, it always empty.

Hi @raf, I will try to address your questions one by one.

role

Please add the role field to your user’s contact document, then it should load as role inside the user group. Also, please note this comment:

inputs

You can read about the inputs group in the app and contact forms here. In short:

Data needed during the completion of the form (eg patient’s name, prior information) is passed into the inputs group.

init

I couldn’t find any resource explaining the init group, sorry about that. I have seen it being used mostly in the contact forms to store or calculate something temporarily (which you don’t want to store in the resulting database document).

For example, in the person-create form in the default config, inside the init group, we are pulling the parent information such as name, and type. You can also see a calculate field: type_label which is used as a hint (Household). The user can see these fields (unless they are hidden or a calculated field), but they are not saved in the database document upon submission.

contact_uuid

The contact_uuid field above is used to bind the contact document so that the fields after it (name, role, date_of_birth) are populated. The binding is done by the special syntax used in the appearance column. You can read about it here.

./ vs ../

In XPath, . selects the context node and .. selects the parent of the context node. Since role and user_contact_info, are at the same level (siblings), we need to go to the parent and come to it.

I hope that all your questions have been answered. If I missed something, or need to clarify more, please let me know.

@binod
Thank you for taking the time and explaining. I had read that already.
According to your docs:

I can use the doc for the user.

An exemplary user of mine would be:

{
  "_id": "org.couchdb.user:head-niger",
  "_rev": "3-6f8ccf28ec163124c481eeab9e38a56d",
  "name": "head-niger",
  "type": "user",
  "roles": [
    "program_officer",
    "mm-online"
  ],
  "facility_id": "930e8b2d-a7d3-57a3-8fbf-540d785e464f",
  "password_scheme": "pbkdf2",
  "iterations": 10,
  "derived_key": "5785a9687e67d92ba60d38e7828d77bdf716435e",
  "salt": "c398a9f86fabc6d50bb2af17041464ee",
  "known": true
}

For testing, I have tried to load name, type, facility_id, roles, password_scheme, etc.
Beside name, facility_id and contact_id, none of them gives any output, despite using the same approach for all of them.
The only difference is the output for type. It gives as output user-settings although the correct answer would be user.

All a big mystery to me.

Hi @raf, sorry for the confusion.

There is another place where the user document is stored. The user information is pulled from there.
By default, the database is medic, and the document _id would be the same as above: org.couchdb.user:head-niger.
For your user, there should be a document inside medic database which should look something like this:

{
  "_id": "org.couchdb.user:head-niger",
  "_rev": "2-f06f5d47c37d1bd762f42c53b88376e6",
  "name": "head-niger",
  "type": "user-settings",
  "roles": [
    "program_officer",
    "mm-online"
  ],
  "facility_id": "930e8b2d-a7d3-57a3-8fbf-540d785e464f",
  "contact_id": "8a22818c-6c5e-43cd-bcfa-ae8f04279070",
  "known": true
}

All these fields are available in the form, except for roles, which is an array.

<user>
    <name>head-niger</name>
    <contact_id>8a22818c-6c5e-43cd-bcfa-ae8f04279070</contact_id>
    <facility_id>930e8b2d-a7d3-57a3-8fbf-540d785e464f</facility_id>
    <known>true</known>
    <type>user-settings</type>
    <_id>org.couchdb.user:head-niger</_id>
    <_rev>2-f06f5d47c37d1bd762f42c53b88376e6</_rev>
    <roles/>
</user>

That’s why we take the contact_id, go to the associated contact document, and look for the role field there. For that to work, the role field should be added to the contact form in the first place.

If you are interested to learn more about how the data is transferred from CouchDB to the XML form, you can find the binding taking place here in the cht-core source.

1 Like