-
Notifications
You must be signed in to change notification settings - Fork 33
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
global: improved domain/user indexing, data flow, search and REST API #124
global: improved domain/user indexing, data flow, search and REST API #124
Conversation
@@ -8,62 +8,111 @@ | |||
# details. | |||
|
|||
"""API classes for user and group management in Invenio.""" | |||
import 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.
Major changes in this file and models.py
to make make the record classes behave more like normal records, and to clearly separating the responsibilities of parsing the user/role/domain objects from Invenio-accounts.
Now UserAggregate/GroupAggregate/DomainAggregate are records that is responsible for harmonising data access from search index and DB. the <Model>AggregateModel
objects are responsible for metadata storage and for parsing the Invenio-accounts user/role/domain models.
"""Emulated PID""" | ||
|
||
|
||
class AggregatePID: |
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.
Provides an interface that is needed by Records-Resources service layer (otherwise we have to implement all the service methods).
@@ -28,6 +28,7 @@ def dump(self, record, data): | |||
email_visible = record.preferences["email_visibility"] | |||
if email_visible == "public": | |||
data[self.field] = email | |||
data[self.hidden_field] = email |
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.
We now always index the email address in the hidden field as well so we can make it searchable for admins.
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.
the mappings still have
"email_hidden": {
"type": "keyword",
"index": "false"
},
which means the field won't be indexed, is it intentional ?
EDIT: just saw the new mapping, all good, ignore the above
nit: we could remove the else below and dump the hidden field at all times?
ATTENTION for maintainers: will need reindexing
@@ -1,31 +1,4 @@ | |||
{ | |||
"settings": { |
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 all moved to the python side now
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.
we shouldn't modify the mapping since we add the v2.0.0, otherwise we lose the backwards compatibility, no? Unless I have misunderstood the intention of this change
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.
Correct, this is a mistake 👍 The mapping should not be modified
@@ -0,0 +1,33 @@ | |||
# -*- coding: utf-8 -*- | |||
# | |||
# Copyright (C) 2022 TU Wien. |
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.
TODO: Fix header
@@ -35,12 +39,13 @@ class UsersResourceConfig(RecordResourceConfig): | |||
url_prefix = "/users" | |||
routes = { | |||
"list": "", | |||
"moderation_search": "/moderation", | |||
"search_all": "/all", |
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.
Comment: Changing name here, because the API is more than just moderation, it's provides all the admin interface with all the user information
|
||
@validates_schema | ||
def validate_props(self, data, **kwargs): | ||
"""Apply instance specific validation on props.""" |
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.
We allow each instance to define their own schema for extra properties on a domain (by default just stores the country
).
return current_users_service.check_permission(ctx["identity"], "manage") | ||
|
||
|
||
def word_domain_status(node): |
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.
allows searching uses from their domain status: domain.status:verified
@@ -63,41 +91,69 @@ class UserSearchOptions(SearchOptions, SearchOptionsMixin): | |||
SortParam, | |||
FixedPagination, | |||
FacetsParam, | |||
ModerationFilterParam.factory(param="is_blocked", field="blocked_at"), |
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.
Removing this, because these shouldnt' be available on he API used for searching members to invite.
] | ||
|
||
facets = { | ||
"email_domain": facets.email_domain, |
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.
We should also not have faces on the API where users can search for members.
@@ -145,16 +138,13 @@ def block(self, identity, id_, uow=None): | |||
|
|||
self.require_permission(identity, "manage", record=user) | |||
|
|||
if user.blocked: |
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.
TODO: We should not allow an admin to block themselves as well.
|
||
from invenio_users_resources.proxies import current_actions_registry | ||
from invenio_users_resources.services.users.lock import ModerationMutex | ||
|
||
|
||
@pytest.fixture() |
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.
Previously the service did not check if a user was already blocked, now that it checks the test code doesnt' work anymore because the same users is being blocked multiple times, so this was a quick way of fixing the test to work.
I recognize my approaches may seem detail-oriented, but it's in service of our collective effort to enhance the project. I welcome any discussions on these. |
QueryParser, | ||
SearchFieldTransformer, | ||
) | ||
from luqum.tree import Word |
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.
minor: direct import from implicit dependency (installed by another module, records-resources)
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 think this is ok, because Records-Resources is in charge of setting the right dependency of luqum
- otherwise we get issues later on, when we have to upgrade luqum in all places where it is used.
class UserSearchOptions(SearchOptions, SearchOptionsMixin): | ||
"""Search options.""" | ||
|
||
pagination_options = { | ||
"default_results_per_page": 10, | ||
"default_max_results": 10, | ||
} | ||
# ATTENTION: Risk of leaking account information!!! |
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.
❤️
2b07c94
to
2fc03be
Compare
Thanks for the review! I've integrated the changes now. |
* Refactors data flow and indexing so that the aggregate data model is in charge of all data parsing of the user and role model as well as indexing * Adds domain data and user identities and further attributes to the users index and makes them searchable for admins. * Fixes indexing/facets of email domain values. * Allows admins to search for restricted email addresses. * Add admin facets for domain, account status, domain status. * Add sort options to admin user search.
be78fc7
to
7a673ce
Compare
Co-authored-by: Karolina Przerwa <[email protected]> Co-authored-by: Sam Arbid <[email protected]>
7a673ce
to
520e2e0
Compare
Description
Depends on inveniosoftware/invenio-accounts#475
Refactors data flow and indexing so that the aggregate data model is in charge of all data parsing of the user and role model as well as indexing
Adds domain data and user identities and further attributes to the users index and makes them searchable for admins.
Fixes indexing/facets of email domain values.
Allows admins to search for restricted email addresses.
Add admin facets for domain, account status, domain status.
Add sort options to admin user search.
INCOMPATIBLE: There's a new users index, so when deployed all users will have to be reindexed, and not sure how the code will work with having users from both indexes at the same time. Probably requires downtime to deploy.
Note, right now the denormalised information in the index about the domain is not updated when the domain is updated. However, as soon as a user logins, update profile etc it is updated. Later we can add a task that one a domainn is updated we also reindex the users.
Checklist
Ticks in all boxes and 🟢 on all GitHub actions status checks are required to merge:
Third-party code
If you've added third-party code (copy/pasted or new dependencies), please reach out to an architect.
Reminder
By using GitHub, you have already agreed to the GitHub’s Terms of Service including that: