<!-- 
RSS generated by JIRA (1001.0.0-SNAPSHOT#100246-sha1:7a5c50119eb0633d306e14180817ddef5e80c75d) at Thu Feb 08 23:04:46 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>FOLIO Jira</title>
    <link>https://folio-org.atlassian.net</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>1001.0.0-SNAPSHOT</version>
        <build-number>100246</build-number>
        <build-date>07-02-2024</build-date>
    </build-info>

<item>
            <title>[FOLIO-305] Location-related permissions in auth</title>
                <link>https://folio-org.atlassian.net/browse/FOLIO-305</link>
                <project id="10290" key="FOLIO">FOLIO</project>
                    <description>&lt;p&gt;Filip&apos;s wireframes introduced a concept of location (circ desk, cataloging), and the idea that the permissions what a user may do depending on the location. Explore how this would change the auth design we have for now.&lt;/p&gt;</description>
                <environment></environment>
        <key id="79929">FOLIO-305</key>
            <summary>Location-related permissions in auth</summary>
                <type id="10002" iconUrl="https://folio-org.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10322?size=medium">New Feature</type>
                                            <priority id="10001" iconUrl="https://dev.folio.org/assets/jira-priority/jira-p2.svg">P2</priority>
                        <status id="6" iconUrl="https://folio-org.atlassian.net/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="green"/>
                                    <resolution id="10003">Done</resolution>
                                                        <assignee accountid="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a">Heikki Levanto</assignee>
                                                                <reporter accountid="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a">Heikki Levanto</reporter>
                                    <labels>
                            <label>sprint2</label>
                    </labels>
                <created>Thu, 8 Sep 2016 12:20:28 +0000</created>
                <updated>Mon, 12 Nov 2018 14:23:15 +0000</updated>
                            <resolved>Thu, 3 Nov 2016 12:38:33 +0000</resolved>
                                                                        <due></due>
                            <votes>0</votes>
                                    <watches>2</watches>
                                                    <timespent seconds="109800">3 days, 6 hours, 30 minutes</timespent>
                                <comments>
                                                            <comment id="191220" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Thu, 8 Sep 2016 12:22:01 +0000"  >&lt;p&gt;It may be that in the future there will be some other deciding factor instead (or in addition to?) location. Better see if we can make this flexible enough.&lt;/p&gt;</comment>
                                                            <comment id="191222" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Fri, 9 Sep 2016 09:03:35 +0000"  >&lt;p&gt;See also &lt;a href=&quot;https://discuss.folio.org/t/making-a-distinction-between-patrons-and-system-users-particularly-with-a-perspective-on-permissions/202&quot; class=&quot;external-link&quot; rel=&quot;nofollow noreferrer&quot;&gt;https://discuss.folio.org/t/making-a-distinction-between-patrons-and-system-users-particularly-with-a-perspective-on-permissions/202&lt;/a&gt;&lt;/p&gt;</comment>
                                                            <comment id="191224" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Fri, 9 Sep 2016 10:38:20 +0000"  >&lt;p&gt;Taking a look at Filip&apos;s wireframe, listing where the location seems to be involved:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;After login, there is a &quot;Choose Branch&quot; dialog&lt;/li&gt;
	&lt;li&gt;Displayed as a one-character blob on top of the profile icon, the rightmost button on the top bar&lt;/li&gt;
	&lt;li&gt;In the pulldown menu from the same button, there is a place to select a different location&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Thinking about other places where locations could be involved:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Settings / Users / Staff member permissions has a list of permission sets, where you can define what individual permissions and permission sets are included in a set. No mention of the location. Maybe it should be there, somehow. It does list persons who have this permission set.&lt;/li&gt;
&lt;/ul&gt;

</comment>
                                                            <comment id="191226" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Fri, 9 Sep 2016 10:59:00 +0000"  >&lt;p&gt;If the user is allowed to change location just like that, then the location will not offer much additional security. In that case we sould probably view it only as a piece of state in the UI, helping to make some parts more visible when relevant, and less so when not. Maybe also ending up in some audit logs, etc.  But I am not (at all) sure how that could be confifgured... &lt;/p&gt;

&lt;p&gt;On the other hand, if the location is strictly controlled - like paying fines can only be done at the machine on the fines counter (where the money box is), then it makes more sense wrt security. But again, this needs to be configured somehow, by someone who has the permission to do so...&lt;/p&gt;
</comment>
                                                            <comment id="191228" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Fri, 9 Sep 2016 11:31:10 +0000"  >&lt;p&gt;Okapi&apos;s permission model only operates with simple string permissions, like &quot;patron-read-sensitive&quot; or &quot;forgive-fine&quot;. The auth module will compile all these by going through the permission sets the user has, and recursing into the permission sets contained in those, until all we have is a list of real permissions. This fits well with Filip&apos;s permission set thinking. At the moment, when the user logs in, the auth module produces a token that the UI is supposed to pass back at every request. When a request comes to Okapi, it extracts the user from the toke, looks up the permissions given to the user, and creates those permission bits.&lt;/p&gt;

&lt;p&gt;I am speculating if we can fake the location-dependent permissions within this model. &lt;/p&gt;

&lt;p&gt;Here is one possible way:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;We extend the user record to contain a set of locations, and additional permissions those locations give.&lt;/li&gt;
	&lt;li&gt;We extend the auth token to include the current location of the user (if any)&lt;/li&gt;
	&lt;li&gt;We extend the code that calculates the full list of permissions to include the permissions for that location&lt;/li&gt;
	&lt;li&gt;We add a service to the auth module to switch location. It takes the current token, and the new location, and produces a new token that contains the location.&lt;/li&gt;
&lt;/ul&gt;

</comment>
                                                            <comment id="191229" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Fri, 9 Sep 2016 11:43:59 +0000"  >&lt;p&gt;If we implement this, I suggest we immediately make it not just location, but a set of tags, each working the same way. Location would be one of them, but we could also have some kind of role, position, or even current task.&lt;/p&gt;

&lt;p&gt;Of course, the auth service that changes location will have to log it in some kind of audit log.&lt;/p&gt;

&lt;p&gt;There is one small drawback for this design: The location-dependent permissions need to be defined individually for each user. But there is a way around this too: If we seed the permission list with the name of a permission set like &quot;location-fine-global&quot;, then we can define that set to contain the permissions given to anyone at that location. Of course this set may be empty.&lt;/p&gt;

&lt;p&gt;Each user still needs to have a list of permitted locations. Those can come from a template when the user is created, or updated individually or in a batch, using some automation tool (for all users who have location &quot;circ-1&quot; or &quot;circ-2&quot;, add also location &quot;circ-3&quot; with the &quot;location-circ-3-global&quot; permission set in it).&lt;/p&gt;</comment>
                                                            <comment id="191231" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Mon, 12 Sep 2016 08:22:11 +0000"  >&lt;p&gt;Oh, a side note: This design is so much compatible with our current way of thinking that we can retrofit it in when necessary. All functional changes will be local to the auth module, Okapi and apps will not notice anything changed. We will need a bit of management functions to set user permissions for different locations, and a function for the user to change location, but everything else will just keep working.&lt;/p&gt;</comment>
                                                            <comment id="191233" author="5c38e8d616ac1e4f7cbc660a" created="Wed, 28 Sep 2016 20:30:28 +0000"  >&lt;p&gt;Thinking this through, I thinking maybe I want to make things a little more generic than &quot;location.&quot; How does this look?&lt;/p&gt;

&lt;p&gt;The user record currently looks like this:&lt;/p&gt;

{
	&quot;user_name&quot; : &quot;jack&quot;,
	&quot;tenant&quot; : &quot;diku&quot;,
	&quot;user_permissions&quot; : [ &quot;thing.read&quot;, &quot;thing.see_sensitive&quot; ]
}

&lt;p&gt;In order to enable flag-based permissions, we can modify the user record to look like the following:&lt;/p&gt;

&lt;p&gt;{&lt;br/&gt;
	&quot;user_name&quot; : &quot;jack&quot;,&lt;br/&gt;
	&quot;tenant&quot; : &quot;diku&quot;,&lt;br/&gt;
	&quot;user_permissions&quot; : &lt;/p&gt;
{
		&quot;_&quot; : [ &quot;thing.read&quot;],
		&quot;location.front_desk&quot; : [ &quot;patron.fines&quot;, &quot;circulation.all&quot; ]
		&quot;location.back_office&quot; : [ &quot;patron.all&quot;, &quot;circulation.all&quot; ]
	}
&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;In order to request flag-based permissions, we&apos;ll add an option &quot;flags&quot; parameter to the permissions request URL.&lt;/p&gt;

&lt;p&gt;GET /perms/users/jack/permissions would yield [ &quot;thing.read&quot;, &quot;thing.see_sensitive&quot; ]&lt;/p&gt;

&lt;p&gt;GET /perms/users/jack/permissions?flag=location.front_desk would yield [ &quot;thing.read&quot;, &quot;thing.see_sensitive&quot;, &quot;patron.fines&quot;, &quot;circulation.all&quot; ]&lt;/p&gt;

&lt;p&gt;Permissions flags would just be stored as a field in the user&apos;s JWT:&lt;/p&gt;

{
	&quot;sub&quot; : &quot;jack&quot;,
	&quot;tenant&quot; : &quot;diku&quot;,
	permissions_flags&quot; : [ &quot;location.front_desk&quot; ]
	&#8230;
}

&lt;p&gt;When the Authz module is processing a request, it will look at the JWT and check for any permissions_flags defined. If present, it will use them when it requests the permissions for that user from the Permissions module.&lt;/p&gt;

&lt;p&gt;In order to change flags (e.g., to a change a user&apos;s location), the user would simply need to log in again, and provide a &quot;permissions_flag&quot; parameter. E.g.: &lt;/p&gt;

&lt;p&gt;/authn/login?permissions_flag=location.front_desk&lt;/p&gt;
</comment>
                                                            <comment id="191235" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Thu, 29 Sep 2016 09:12:26 +0000"  >&lt;p&gt;Looks about right.&lt;/p&gt;

&lt;p&gt;Just to be clear, the user may have more than one flag in the JWT, and the permissions call can take a (comma-separated?) list of flags in the parameter. Right?&lt;/p&gt;

&lt;p&gt;But I disagree that the user would need to log in again. I think we should have a new call for changing the flags, that the user can issue. It should not require a full logging in, with passwords and all that. It would just take the existing JWT, change the flags as requested, sign it, and return as a new JWT. This comes directly from Filip&apos;s UI demo, where there was a button to click to change location.&lt;/p&gt;

&lt;p&gt;If we need, we can later make a system where the change-location would need a permission, and use our permission management system to lock users into their flag sets. But that gets hairy pretty soon, and we don&apos;t really know what the different installations will need. Better loave that for later.&lt;/p&gt;</comment>
                                                            <comment id="191237" author="5c38e8d616ac1e4f7cbc660a" created="Thu, 29 Sep 2016 16:07:58 +0000"  >&lt;p&gt;Yes, I intended for the flags to permit multiple instances. I should have spelled that out.&lt;/p&gt;

&lt;p&gt;I see your point about not requiring a login. We can easily make a &quot;refresh&quot; endpoint to allow a user to request a new token, possibly with new flags enabled.&lt;/p&gt;</comment>
                                                            <comment id="191238" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Mon, 31 Oct 2016 13:01:26 +0000"  >&lt;p&gt;This is not yet implemented, right?&lt;/p&gt;

&lt;p&gt;If we make that &quot;refresh&quot; endpoint to change flags in the current token, we could also allow a GET request to retrieve a list of flags and their known values (from the user record), so that the UI can offer a nice way to select the location, or other flags.&lt;/p&gt;</comment>
                                                            <comment id="191240" author="5c38e8d616ac1e4f7cbc660a" created="Mon, 31 Oct 2016 13:55:01 +0000"  >&lt;p&gt;Correct, no implementation has been done at this point.&lt;/p&gt;

&lt;p&gt;Which module do we envision serving up the flags?&lt;/p&gt;</comment>
                                                            <comment id="191242" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Mon, 31 Oct 2016 14:13:53 +0000"  >&lt;p&gt;The way I see it, the permissions module keeps a list of various flags and the permissions associated for those, for each user. So it should be the permission module that can also provide the list of allowed flags for the (current) user.&lt;/p&gt;

&lt;p&gt;Of course, the service to change the token to include new flags would have to be in the module that can sign new tokens, the one we just renamed to authtoken_module.&lt;/p&gt;</comment>
                                                            <comment id="191244" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Tue, 1 Nov 2016 10:18:56 +0000"  >&lt;p&gt;As far as I can see, Filip&apos;s prototype talks about location in two places: Right after logging in it asks the user to choose a location, and in the top-menu, the rightmost button is user info, which includes a pull-down to change location.&lt;/p&gt;

&lt;p&gt;I would imagine that we need some supporting functions, like defining what locations we may have in the system, what locations a given user may choose, and what additional permissions any location gives to the user.&lt;/p&gt;

&lt;p&gt;Earlier in this issue, we thought that it would make sense not to limit the thing to locations only, but to allow various other flags for things like roles, tasks, or situations. And if we allow the flag to be other than location, it may make sense to allow the user to choose more than one at a time. But that may confuse the UI. Still, since it is so easy to add, it makes sense to allow this on the back end anyway.&lt;/p&gt;

&lt;p&gt;I can see two ways how a user may be given the permission to operate on a given location: Either directly, or as a part of a permission set or role (which I see technically the same). I think a permission set is more powerful.&lt;/p&gt;

&lt;p&gt;For example, a permission set &quot;music library circulation&quot; would (directly, or indirectly through other sets it includes) grant the user access to &quot;location:music.library.circulation.desk&quot; and if the user has selected that location, access to permissions like &quot;circulate.materialtype.music&quot; or &quot;reservation.location.music.listening.room&quot;. (These will again expand into more technical permissions like &quot;reservation.location.write&quot; and &quot;.read&quot;)&lt;/p&gt;

&lt;p&gt;Filip, what do you think? Have I misunderstood something in your design?&lt;/p&gt;
</comment>
                                                            <comment id="191246" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Wed, 2 Nov 2016 13:39:13 +0000"  >&lt;p&gt;Here is my plan how I would implement this:&lt;/p&gt;

&lt;p&gt;authtoken_module:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Add a new field in the token, like this: ` &quot;flags&quot;: [ &quot;location.frontdesk&quot;, &quot;location.musiclibrary&quot;, &quot;task.newuser.intro&quot; ]`&lt;/li&gt;
	&lt;li&gt;Add a new endpoint to set flags. Returns a new token with the same user and tenant etc, but with new flags. Possibly with params for adding, removing, or replacing tags one at a time.&lt;/li&gt;
	&lt;li&gt;Add a helper method in OkapiToken to extract current flags, and also a new endpoint to return the same&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;permissions_module:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;In the routine that calculatesthe full permission set for the user, take an extra parameter that lists the flags the user has (as in &quot;location.frontdesk&quot;, and applies those permissions as well as the default ones.&lt;/li&gt;
	&lt;li&gt;Change the permission structure (/perms/permissions) to include not only the regular permissions, but also permissions for each flag, so that each permission set can contain permissions that depend on a flag.&lt;/li&gt;
	&lt;li&gt;No need to change the structures under /perms/users, the users will get permission (sets) that will contain permissions for the various flags.&lt;/li&gt;
	&lt;li&gt;Add a new endpoint somewhere under /perms/users/... to list all the flags that give the user extra permissions. This will be useful in the UI for building a pulldown list where the user chan change location or other flags.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I think this should cover it.&lt;/p&gt;</comment>
                                                            <comment id="191248" author="712020:38d1a08f-86a8-4df2-9191-239b16b0a81a" created="Thu, 3 Nov 2016 12:38:33 +0000"  >&lt;p&gt;Design is complete, implementation will happen in some other issue... Link to this when that time comes.&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10000">
                    <name>Blocks</name>
                                            <outwardlinks description="blocks">
                                        <issuelink>
            <issuekey id="79400">FOLIO-326</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10000" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummarycf">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10019" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|hzxg4f:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10020" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10024" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>[CHART] Date of First Response</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Wed, 28 Sep 2016 20:30:28 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10025" key="com.atlassian.jira.ext.charting:timeinstatus">
                        <customfieldname>[CHART] Time in Status</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>