-
Notifications
You must be signed in to change notification settings - Fork 68
Refactor Bean Scopes: User, Role, Authority, Client, LdapGroup, LdapServer forms #6770
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
base: main
Are you sure you want to change the base?
Conversation
…ity and role form.
1e46493 to
f12ff8e
Compare
1f63b41 to
a5000d2
Compare
…embering row index of referred list view.
…n be restored after navigating back from an edit view.
Kitodo/src/main/java/org/kitodo/production/forms/LdapServerListView.java
Fixed
Show fixed
Hide fixed
…sts between reloads and when editing a user.
|
@solth After refactoring the user list view from
I moved these state information into the URL as query parameters, which seems to work fine. I even keep these state information available by forwarding them to the respective edit views and reloading them after navigating back to the source list view (via another query parameter In general, I think this approach works fine and now would allow to, e.g., create bookmarks with existing sorting and filter criteria. However, I see a problem for the task and process list, and their respective filter options. When navigating to the task or process list, the current page and sorting options are reset to their defaults, but the filter option is loaded from the session scope. You can navigate anywhere in Kitodo.Production and still have the same filter option active when returning to the task or process list. I am not entirely sure, but I think this is most certainly desired behavior. Anyway, this long-term information about the current active filter in the task and process list cannot be modeled as query parameters (alone). We could try cookies? What do you think? |
Would it be an option to store only the filter-related information in a small, dedicated @SessionScoped bean and inject it into the @ViewScoped process and task list views? |
Yes, of course this would be possible. Other options would be, storing it:
In any case I would suggest storing all relevant list view options (including the filter) in URL query parameters as well (overwriting any long-term preferences), such that you can easily save various filters via browser bookmarks. |
…ons in authority edit view and role list view.
solth
left a comment
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.
@thomaslow thanks a lot for this pull request. The implementation looks very solid and it's great that we will finally have properly scoped beans in Kitodo! I encountered just a few minor issues (see below). And please do not forget to rebase against/merge with the main branch (if you want to wait for #6803 to be merged that's fine by me as well)
|
|
||
| private static final Logger logger = LogManager.getLogger(ClientListView.class); | ||
|
|
||
| public static final String VIEW_PATH = MessageFormat.format(REDIRECT_PATH, "users") + "&tabIndex=2"; |
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 wonder whether having static tab index values is a good idea here. In case the user does not have the permission to see the user list, for example, the index for all following tabs should be decreased accordingly, shouldn't it (same applies to the other views as well, of course)?
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.
Good point. I was thinking about changing the view parameter to something like tab=users, tab=roles (because it "looks" better), but noticed that the view parameter tabIndex was used in other parts of Kitodo.Production, so I simply reused that instead. I didn't think about users with restricted permissions that will have a different tab order. I'll change it to tab=<view_name>.
|
|
||
| public static final String VIEW_PATH = MessageFormat.format(REDIRECT_PATH, "users") + "&tabIndex=5"; | ||
|
|
||
| private static final Logger logger = LogManager.getLogger(LdapServerEditView.class); |
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.
| private static final Logger logger = LogManager.getLogger(LdapServerEditView.class); | |
| private static final Logger logger = LogManager.getLogger(LdapServerListView.class); |
| * @param role the role to be removed | ||
| * @return true if role was removed | ||
| */ | ||
| public static boolean deleteRole(Role role) { |
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.
Maybe we can move this method to the RoleService, as it contains quite a bit of business logic and isn't directly called from the template? If it stays in this class, it could probably be made private, since it is only called from within this class itself, isn't it?
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.
Yes, you are right. The view-independent part should be moved to the RoleService. I'll update that.
| * @return true if user clients data was saved | ||
| */ | ||
| public boolean save() { | ||
| return 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.
I am not quite sure why we need this method. It only ever returns true. Have you added this because some tabs have actual conditions that are checked before the user can be saved?
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.
Yes, I was trying to establish a method "pattern" of common save and load methods for different edit view tabs. Maybe I should refactor this into a base class BaseEditTabView.
| return Collections.emptySet(); | ||
| } | ||
| KitodoPassword validPassword = new KitodoPassword(passwordToEncrypt); | ||
| ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); |
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.
My IDE tells me that ValidatorFactor is AutoClosable and should be used with try-with-resources. Would something like
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
Validator validator = factory.getValidator();
return validator.validate(validPassword);
}
work?
| * Check whether the old password matches the password stored in the database. | ||
| * | ||
| * @return true if the old password does not match the password stored in the database | ||
| */ | ||
| private boolean isOldPasswordInvalid() { | ||
| if (!ServiceManager.getSecurityAccessService().hasAuthorityToEditUser()) { | ||
| return !Objects.equals(this.oldPassword, passwordEncoder.decrypt(this.userObject.getPassword())); | ||
| } | ||
| return false; |
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.
Despite being just a few lines, I find this whole method confusing because of the multiple negations (e.g. "invalid" instead of "valid", if(!ServicManager...), return !Objects.equals etc.). I know you just copied this method from the UserForm and didn't author it, but perhaps now would be a good opportunity to simplify the code?
| /** | ||
| * Update the current browser URL to include the selected query parameter and value. | ||
| * | ||
| * @param str key the query parmaeter name |
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.
| * @param str key the query parmaeter name | |
| * @param str key the query parameter name |
| id="yesButton" | ||
| value="#{msgs.yes}" | ||
| action="#{UserForm.resetTasksAndDeleteUser}" | ||
| action="#{UserListView.resetTasksAndDeleteUser(confirmResetTasksDialogUser)}" |
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.
| action="#{UserListView.resetTasksAndDeleteUser(confirmResetTasksDialogUser)}" | |
| action="#{UserListView.resetTasksAndDeleteUser(UserListView.confirmResetTasksDialogUser)}" |
I think this needs to reference the bean that contains user object, doesn't it? Without it I get a NullPointerException when trying to delete a user with assigned tasks:

|
@solth Thank you for your feedback. I'll update this branch next week. |
This PR refactors all forms on the "users" page from
@SessionScopedto@ViewScoped. In addition, a few minor cleanup improvements are made.Related to: #6456
Updated forms:
UserFormRoleFormAuthorityFormClientFormLdapGroupFormLdapServerFormChanges:
@SessionScopedto@ViewScopedtabIndex- the currently active tabsortField- the field that is used for sortingsortOrder- the order of sortingfirstRow- the first data row shown in the data table (corresponds to a page)filter- the active list filterreferrerListOptions- the list optionssortField,sortOrder,firstRowandfilterencoded in a single parameter such they can be restored when navigating back to the list after editing a single entityDue to the replacement of
UserForm.java,RoleForm.java, ..., merging with the following PR needs to be done more carefully such that any improvements are not lost: