How to get the current session Location without REST Call?

We can get the current session location of the authenticated user through this following REST call,

/ws/rest/v1/appui/session

I would like to know, is there any way to get this session location in Java without calling this REST API? (Like through the context? )

CC : @dkayiwa

Does this help? Context.getUserContext().getLocationId()

It doesn’t provide the current session location information @dkayiwa. I think, the only way is that REST API to access the browser session.

This is what backs that REST API. You can find the relevant Java calls here: https://github.com/openmrs/openmrs-module-appui/blob/master/omod/src/main/java/org/openmrs/module/appui/UiSessionContext.java

Yes, I have explored this file. But I think, I can’t make it through the relevant Java calls. Because this UiSessionContext is initiated with a HttpServletRequest(see here), and the session is fetched through this HttpServletRequest(see here) to get the session location id.

Unfortunately, this class was not registered with the bean. So I couldn’t get this UiSessionContext class through the Context.getRegisteredComponent method also (using this following method),

UiSessionContext uiSessionContext = Context.getRegisteredComponent("appui",UiSessionContext.class);


Are there any way to access the session from the Java, then I can easily get that session location attribute.

CC : @dkayiwa, @darius

Where in the Java code are you talking about? Are you in a controller in the web layer? Or in an API method? If you have access to the HTTP session, in other words from the web lair, you can get the location ID as a session attribute.

@darius I am out of the web layer and need this current location information (need to fetch from the session or anyways) in the API method.

@suthagar23 the “session” is entirely a web layer concept. It doesn’t exist in the API. The OpenMRS API is basically stateless, and there’s no “current location”.

I’m not sure what you’re trying to do. Maybe you could fetch the session location in a web controller, and then pass it to your API layer method.

@darius

Actually, I wanted to follow this scenario(this should be coded within API layer with the help of AOP),

  • User need to select the access Location from the patient dashboard if they configure the Custom definition with the fragment

  • If they didn’t configure the app definition for the patient dashboard(then the user will not get the chance to select the access location), then I need to assign the access location value as the logged in user session location while registering the user.

Here, I can get the session from the fragment Controller class, and pass it to the API layer method (only possible when the fragment is loaded into the web layer). If the user didn’t configure the app definition with my custom fragment, then my custom fragment will not be loaded into the web layer. So the session will not be fetched for passing to the API layer.

CC : @dkayiwa

AFAIK, Now Only we have a way to call that REST API to get the current session location information since it was implemented in the web layer.

Can we customize the UiSessionContext code to store the current session location value into the UserContext as well. Then we can simply fetch the current logged in user location information through the UserContext easily. It will very help full in the future implementation as well

Idea behind this is,

  • Just need to add a line after this line like this following,

    Context.getUserContext().setLocation(sessionLocation);

  • Then we can simply fetch the logged in user location information using,

    Context.getUserContext().getLocationId()

If this is fine, then I can create a ticket and change the code as well :slight_smile:

CC : @dkayiwa @darius

Idea behind this is,

Just need to add a line after this line like this following,

Context.getUserContext().setLocation(sessionLocation);

Then we can simply fetch the logged in user location information using,

Context.getUserContext().getLocationId()

This was not worked as expected :cry:

But I can able to add the logged in user session location information into AdministrationService as a Global Property,

Context.getAdministrationService().setGlobalProperty("sessionLocation", sessionLocation.getId().toString());

It worked for me, and I was able to fetch it in the API layer as well :slight_smile:.

So shall I create a ticket and add this small change to the appui module?

CC : @dkayiwa @darius

No, global properties are, as the name says, global settings, they’re not specific to a single session or request.

I just took a quick peek at the short summary of your GSoC project, and I see it says:

Some implementations want to register users and patients in certain locations. Then access them based on the location that some one has logged in. That way, if some one is logged in a certain location, they should see only those encounters, observations, and patients registered in that location. But the System Developer account should be able to see patients in all locations.

Honestly this does not sound right to me. The way the Reference Application works is that a user simply selects a location when logging in, and there’s no authorization required to choose a login location. I would expect that users are assigned to one or more locations, and when the user logs in they’re allowed to see patients that belong to any of their locations. (But this user-location assignment would be at the API / data model level, not via the web session.)

Honestly this does not sound right to me. The way the Reference Application works is that a user simply selects a location when logging in, and there’s no authorization required to choose a login location. I would expect that users are assigned to one or more locations, and when the user logs in they’re allowed to see patients that belong to any of their locations. (But this user-location assignment would be at the API / data model level, not via the web session.)

Yes @darius , this is the idea behind my implementation :smile:

We will not remove the location selection(login) in the reference application until we reach a potential position on this project. After reaching a potential position, When a user logged in, System will automatically fetch the access location information.

Now the initial scenario will be,

  • If the patient registration dashboard of the system was customized with the location selection fragment(given through this module), then the user will assign the patient to a location! - NO PROBLEM AT THIS POINT

  • But if the patient registration dashboard of the system was not customized with the location selection fragment (some users, they might not change it for now), then the access location for the patient should be fetched from the current user session location - HERE IS THE PROBLEM (I need to fetch the session location information - See here )

So that, I have planned to store the current user location information into a global property from the appui module and decided to fetch that from my module.


Apart from that, there are no JAVA methods to get the current logged-in user session location information from the API Layer, So adding that information into a Global Property as follows will be a solution for those requirements as well!

How did Context.getUserContext().setLocation(sessionLocation) from appui fail to work?

I have tried it, but failed to work @dkayiwa

Can you do a pull request and i see the changes you made in the appui module?

Sure, I will do it @dkayiwa

@dkayiwa

I have checked this method again, and I was able to figure out the issue on this. I have fixed it and I was able to use this method to store the sessionLocation :smile:. So there are no need of Global Property !!

Please find the changes in appui module here :

I was sure that there was no way it would fail to work. :slight_smile:

Hello There I am using LBAC, Is there any api to get the list of assign locations to list in dropdown. I need those locations which are assign to a particular user only. Thanks