New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(get): get more infos from user (DEV-641) #181
Conversation
Open concerns:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A question: how are users treated if they are members of several projects and members of groups of other projects, are these projects and groups retrieved as well? If so, should this information be provided in with the dsp-tools get
command?
About your questions:
- user.py, line 725: I'm not sure if I understand your question: The API route that is used on line 692 does not return the groups and projects, so you need to get the groups and users separately, like you did. What do you mean with "I add the groups and projects two times"? You only add them once to the user you retrieved from the API. Not sure if I miss something here...
- Prefixes of the acutal ontology: I would leave them there. It is correct and it's a useful information. Or is there a reason why it shouldn't be in the ontology? --> I don't really have a strong opinion on that - do what you prefer
- I would leave them there, to me they aren't disturbing. --> I don't really have a strong opinion on that - do what you prefer
knora/dsplib/models/user.py
Outdated
@@ -689,7 +690,7 @@ def getAllUsersForProject(con: Connection, proj_shortcode: str) -> list[Any]: | |||
|
|||
result = con.get(User.ROUTE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I think about it, there is a route to get all users for a specific project, it's:
/admin/projects/shortcode/{{project_shortcode}}/members
It's probably easier to use this for getAllUsersForProject
directly. There are also groups and projects for the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have much to add to this one, beyond the comments Irina has already made
Co-authored-by: irinaschubert <irina.schubert@dasch.swiss> Co-authored-by: Balduin Landolt <33053745+BalduinLandolt@users.noreply.github.com>
Kudos, SonarCloud Quality Gate passed!
|
Thanks to Irina's comment (#181 (comment)) I managed to considerably simplify the code and to resolve the concern I had in #181 (comment). Besides, I implemented your feedback and I also did some refactorings where it seemed useful. The PR has now changed considerably, so I ask you again for a review. |
project_groups = json_obj['permissions']['groupsPerProject'] | ||
for project in project_groups: | ||
if project == Project.SYSTEM_PROJECT: | ||
if Group.PROJECT_SYSTEMADMIN_GROUP in project_groups[project]: | ||
for project_iri, group_memberships in json_obj['permissions']['groupsPerProject'].items(): | ||
if project_iri == Project.SYSTEM_PROJECT: | ||
if Group.PROJECT_SYSTEMADMIN_GROUP in group_memberships: | ||
sysadmin = True | ||
else: | ||
for group in project_groups[project]: | ||
for group in group_memberships: | ||
if group == Group.PROJECT_MEMBER_GROUP: | ||
if in_projects.get(project) is None: | ||
in_projects[project] = False | ||
if in_projects.get(project_iri) is None: | ||
in_projects[project_iri] = False | ||
elif group == Group.PROJECT_ADMIN_GROUP: | ||
in_projects[project] = True | ||
in_projects[project_iri] = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just a refactoring, without semantic modification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
|
||
def createDefinitionFileObj(self): | ||
user = { | ||
members = con.get(f'/admin/projects/shortcode/{proj_shortcode}/members') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this route, the same task can be achieved with less code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one can always find more to change and improve... but I think this should be good for now. (I added some minor remarks nonetheless)
@@ -475,18 +476,17 @@ def fromJsonObj(cls, con: Connection, json_obj: Any): | |||
in_groups: set[str] = set() | |||
if json_obj.get('permissions') is not None and json_obj['permissions'].get('groupsPerProject') is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generally, if x is not None
can normally be rewritten as if not x
(but that doesn't need to be done in this PR... I know it's all over the place in dsp-tools)
if Group.PROJECT_SYSTEMADMIN_GROUP in group_memberships: | ||
sysadmin = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this could be simplified even further (I think): sysadmin = (Group.PROJECT_SYSTEMADMIN_GROUP in group_memberships)
project_groups = json_obj['permissions']['groupsPerProject'] | ||
for project in project_groups: | ||
if project == Project.SYSTEM_PROJECT: | ||
if Group.PROJECT_SYSTEMADMIN_GROUP in project_groups[project]: | ||
for project_iri, group_memberships in json_obj['permissions']['groupsPerProject'].items(): | ||
if project_iri == Project.SYSTEM_PROJECT: | ||
if Group.PROJECT_SYSTEMADMIN_GROUP in group_memberships: | ||
sysadmin = True | ||
else: | ||
for group in project_groups[project]: | ||
for group in group_memberships: | ||
if group == Group.PROJECT_MEMBER_GROUP: | ||
if in_projects.get(project) is None: | ||
in_projects[project] = False | ||
if in_projects.get(project_iri) is None: | ||
in_projects[project_iri] = False | ||
elif group == Group.PROJECT_ADMIN_GROUP: | ||
in_projects[project] = True | ||
in_projects[project_iri] = True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice!
def createDefinitionFileObj(self): | ||
user = { | ||
members = con.get(f'/admin/projects/shortcode/{proj_shortcode}/members') | ||
if members is None or len(members) < 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be simplified to if not members:
(both None
and empty lists/dicts/sets evaluate as false in an if-clause)
if members is None or len(members) < 1: | ||
return None | ||
res: list[User] = [User.fromJsonObj(con, a) for a in members['members']] | ||
res.reverse() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure the order of the objects you get from the API is deterministic (at least if the cache is rebuilt), so this may not reliably reproduce the initial order. But if it works in the cases you tested, feel free to leave it in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to find out if it works as expected (also in the future), you could add a test for this method.
for usr in users: | ||
users_obj.append(usr.createDefinitionFileObj( | ||
con=con, proj_shortname=project.shortname, proj_shortcode=project.shortcode | ||
)) | ||
if verbose: | ||
print(f"\tGot user '{usr.username}'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is usr
intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, rather random
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
if members is None or len(members) < 1: | ||
return None | ||
res: list[User] = [User.fromJsonObj(con, a) for a in members['members']] | ||
res.reverse() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to find out if it works as expected (also in the future), you could add a test for this method.
resolves DEV-641