Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f12ff8e
Refactor bean scopes of user, client, ldap server, ldap group, author…
thomaslow Dec 9, 2025
2b44a7f
Merge branch 'main' into refactor-bean-scopes-user-form
thomaslow Dec 11, 2025
a11c17f
Replace constructor with init method in AuthorityListView.
thomaslow Dec 12, 2025
99b5f3d
Remove LdapGroupEditView constructor.
thomaslow Dec 12, 2025
c45878e
Remove constructor in LdapServerListView.
thomaslow Dec 12, 2025
8867c42
Improve javadoc.
thomaslow Dec 12, 2025
5c42a97
Navigate to respective list view tab after editing an ldap group or s…
thomaslow Dec 12, 2025
4a92d58
Switch to appropriate tab via tabIndex query parameter.
thomaslow Dec 12, 2025
c2f5555
Use Javascript to update tabIndex query parameter when switching tabs.
thomaslow Dec 12, 2025
8e3f152
Update activeTabIndex to use UsersTabView.
thomaslow Dec 12, 2025
55bbe44
Fix codacy errors.
thomaslow Dec 12, 2025
262469b
Merge branch 'main' into refactor-bean-scopes-user-form
thomaslow Dec 16, 2025
a5000d2
Update user edit view metadata tab after merge with pagination editor…
thomaslow Dec 16, 2025
7f7637a
Move session scoped keepPagination logic into URL query parameter rem…
thomaslow Dec 16, 2025
256a4ab
Encode list view sort state as URL query parameters such that they ca…
thomaslow Dec 16, 2025
2424379
Fix filter menu in user list view.
thomaslow Dec 16, 2025
ae438fe
Add missing @Override annotations.
thomaslow Dec 16, 2025
8f76917
Fix selenium tests due to addtional list view url query paramaters in…
thomaslow Dec 16, 2025
1d8eff7
Encode current user list filter as query parameter such that is persi…
thomaslow Dec 17, 2025
9c28cf9
Fix newly saved filters are not listed.
thomaslow Dec 17, 2025
f241a34
Add more javadoc.
thomaslow Dec 17, 2025
d0f1cbf
Merge branch 'main' into refactor-bean-scopes-user-form
thomaslow Jan 2, 2026
a713588
Replace referrerFirstRow view parameter with updated referrerListOpti…
thomaslow Jan 4, 2026
3eaed80
Refactor bean scopes to view scoped for project, template, workflow d…
thomaslow Jan 7, 2026
d861371
Merge branch 'main' into refactor-bean-scopes-user-form
thomaslow Jan 7, 2026
da118fe
Merge branch 'refactor-bean-scopes-user-form' into refactor-bean-scop…
thomaslow Jan 7, 2026
8423ce0
Remove unused method in ProjectsTabView.
thomaslow Jan 7, 2026
d5960cc
Fix project list sortField in DesktopForm after removing sort field m…
thomaslow Jan 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@
*
* @return a list of all roles of the user
*/
public List<Role> getRoles() {

Check notice

Code scanning / CodeQL

Exposing internal representation Note

getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
getRoles exposes the internal representation stored in field roles. The value may be modified
after this call to getRoles
.
initialize(new UserDAO(), this.roles);
if (Objects.isNull(this.roles)) {
this.roles = new ArrayList<>();
Expand Down Expand Up @@ -400,7 +400,7 @@
*
* @return all projects
*/
public List<Project> getProjects() {

Check notice

Code scanning / CodeQL

Exposing internal representation Note

getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
getProjects exposes the internal representation stored in field projects. The value may be modified
after this call to getProjects
.
initialize(new UserDAO(), this.projects);
if (Objects.isNull(this.projects)) {
this.projects = new ArrayList<>();
Expand All @@ -423,7 +423,7 @@
*
* @return the clients
*/
public List<Client> getClients() {

Check notice

Code scanning / CodeQL

Exposing internal representation Note

getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
getClients exposes the internal representation stored in field clients. The value may be modified
after this call to getClients
.
initialize(new UserDAO(), this.clients);
if (Objects.isNull(this.clients)) {
this.clients = new ArrayList<>();
Expand Down Expand Up @@ -690,7 +690,7 @@
* <p>
* To allow recreation of an account with the same login the login is cleaned -
* otherwise it would be blocked eternally by the login existence test performed
* in the UserForm.save() function. In addition, all personally identifiable
* in the UserEditView.save() function. In addition, all personally identifiable
* information is removed from the database as well.
*/
public void selfDestruct() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import org.kitodo.production.enums.FilterString;
import org.kitodo.production.forms.CurrentTaskForm;
import org.kitodo.production.forms.ProcessForm;
import org.kitodo.production.forms.UserForm;
import org.kitodo.production.forms.user.UserListView;
import org.kitodo.production.services.ServiceManager;
import org.kitodo.production.services.data.FilterService;

Expand Down Expand Up @@ -76,7 +76,7 @@ public class FilterMenu {

private ProcessForm processForm = null;
private CurrentTaskForm taskForm = null;
private UserForm userForm = null;
private UserListView userListView = null;
private List<Suggestion> suggestions;
private final List<ParsedFilter> parsedFilters;
private String filterInEditMode;
Expand Down Expand Up @@ -106,10 +106,10 @@ public FilterMenu(CurrentTaskForm taskForm) {
/**
* Constructor of filter menu for users.
*
* @param userForm instance of UserForm
* @param userListView instance of UserListView
*/
public FilterMenu(UserForm userForm) {
this.userForm = userForm;
public FilterMenu(UserListView userListView) {
this.userListView = userListView;
suggestions = createSuggestionsForUserCategory("");
parsedFilters = new ArrayList<>();
}
Expand Down Expand Up @@ -148,7 +148,7 @@ public void updateSuggestions(String input) {
suggestions = createSuggestionsForProcessCategory(input);
} else if (Objects.nonNull(taskForm)) {
suggestions = createSuggestionsForTaskCategory(input);
} else if (Objects.nonNull(userForm)) {
} else if (Objects.nonNull(userListView)) {
suggestions = createSuggestionsForUserCategory(input);
}
} else {
Expand Down Expand Up @@ -178,7 +178,7 @@ public void updateSuggestions(String input) {
String category = matcherPreviousCategory.find() ? matcherPreviousCategory.group() : "";
suggestions = createSuggestionsForTaskValue(checkFilterCategory(category, taskCategories), lastPart);
}
} else if (Objects.nonNull(userForm)) {
} else if (Objects.nonNull(userListView)) {
if (matcherNextCategory.find()) {
// strings ends with " | "
suggestions = createSuggestionsForUserCategory(matcherNextCategory.group());
Expand Down Expand Up @@ -399,8 +399,8 @@ public void updateFilters() {
processForm.setFilter(newFilter.toString());
} else if (Objects.nonNull(taskForm)) {
taskForm.setFilter(newFilter.toString());
} else if (Objects.nonNull(userForm)) {
userForm.setFilter(newFilter.toString());
} else if (Objects.nonNull(userListView)) {
userListView.setFilter(newFilter.toString());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
import java.text.MessageFormat;
import java.util.Objects;

import jakarta.enterprise.context.SessionScoped;
import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;

import org.apache.logging.log4j.LogManager;
Expand All @@ -23,28 +24,26 @@
import org.kitodo.data.database.exceptions.DAOException;
import org.kitodo.production.enums.ObjectType;
import org.kitodo.production.helper.Helper;
import org.kitodo.production.model.LazyBeanModel;
import org.kitodo.production.services.ServiceManager;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;

@Named("AuthorityForm")
@SessionScoped
public class AuthorityForm extends BaseForm {
private static final Logger logger = LogManager.getLogger(AuthorityForm.class);
private Authority authority = new Authority();
@Named("AuthorityEditView")
@ViewScoped
public class AuthorityEditView extends BaseEditView {

public static final String VIEW_PATH = MessageFormat.format(REDIRECT_PATH, "authorityEdit");

private static final Logger logger = LogManager.getLogger(AuthorityEditView.class);

private Authority authority;
private String title;
private String type;
private final String authorityEditPath = MessageFormat.format(REDIRECT_PATH, "authorityEdit");

/**
* Default constructor that also sets the LazyBeanModel instance of this
* bean.
* Initialize AuthorityEditView.
*/
public AuthorityForm() {
super();
super.setLazyBeanModel(new LazyBeanModel(ServiceManager.getAuthorityService()));
sortBy = SortMeta.builder().field("title").order(SortOrder.ASCENDING).build();
@PostConstruct
public void init() {
authority = new Authority();
}

/**
Expand Down Expand Up @@ -85,16 +84,6 @@ public void setType(String type) {
this.type = type;
}

/**
* Create new authority.
*
* @return page address
*/
public String newAuthority() {
this.authority = new Authority();
return authorityEditPath;
}

/**
* Save authority.
*
Expand All @@ -104,30 +93,13 @@ public String save() {
try {
this.authority.setTitle(this.title + "_" + this.type);
ServiceManager.getAuthorityService().save(this.authority);
return usersPage;
return AuthorityListView.VIEW_PATH + "&" + getReferrerListOptions();
} catch (DAOException e) {
Helper.setErrorMessage(ERROR_SAVING, new Object[] {ObjectType.AUTHORITY.getTranslationSingular() }, logger,
e);
Helper.setErrorMessage(ERROR_SAVING, new Object[] {ObjectType.AUTHORITY.getTranslationSingular() }, logger, e);
return this.stayOnCurrentPage;
}
}

/**
* Remove authority.
*/
public void delete() {
try {
if (!this.authority.getRoles().isEmpty()) {
Helper.setErrorMessage("authorityAssignedError");
return;
}
ServiceManager.getAuthorityService().remove(this.authority);
} catch (DAOException e) {
Helper.setErrorMessage(ERROR_DELETING, new Object[] {ObjectType.AUTHORITY.getTranslationSingular() },
logger, e);
}
}

/**
* Method being used as viewAction for authority edit form.
*
Expand All @@ -136,38 +108,17 @@ public void delete() {
*/
public void load(int id) {
if (!Objects.equals(id, 0)) {
setAuthorityById(id);
try {
authority = ServiceManager.getAuthorityService().getById(id);
title = authority.getTitleWithoutSuffix();
type = authority.getType();
} catch (DAOException e) {
Helper.setErrorMessage(ERROR_LOADING_ONE, new Object[] {ObjectType.ROLE.getTranslationSingular(), id }, logger, e);
}
}
setSaveDisabled(true);
}

/**
* Set authority by id.
*
* @param id
* ID of authority to set
*/
public void setAuthorityById(int id) {
try {
setAuthority(ServiceManager.getAuthorityService().getById(id));
} catch (DAOException e) {
Helper.setErrorMessage(ERROR_LOADING_ONE, new Object[] {ObjectType.ROLE.getTranslationSingular(), id },
logger, e);
}
}

/**
* Set authority.
*
* @param authority
* as org.kitodo.data.database.beans.Authority
*/
public void setAuthority(Authority authority) {
this.authority = authority;
this.title = this.authority.getTitleWithoutSuffix();
this.type = this.authority.getType();
}

/**
* Get authority.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* This file is part of the Kitodo project.
*
* It is licensed under GNU General Public License version 3 or later.
*
* For the full copyright and license information, please read the
* GPL3-License.txt file that was distributed with this source code.
*/

package org.kitodo.production.forms;

import java.text.MessageFormat;
import java.util.Set;

import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;

import org.kitodo.production.model.LazyBeanModel;
import org.kitodo.production.services.ServiceManager;
import org.primefaces.model.SortMeta;
import org.primefaces.model.SortOrder;

@Named("AuthorityListView")
@ViewScoped
public class AuthorityListView extends BaseListView {

public static final String VIEW_PATH = MessageFormat.format(REDIRECT_PATH, "users") + "&tabIndex=3";

/**
* Initialize AuthorityListView.
*/
@PostConstruct
public void init() {
setLazyBeanModel(new LazyBeanModel(ServiceManager.getAuthorityService()));
sortBy = SortMeta.builder().field("title").order(SortOrder.ASCENDING).build();
}

/**
* Navigate to the authority edit page to create a new authority.
*
* @return page address
*/
public String newAuthority() {
return AuthorityEditView.VIEW_PATH;
}

/**
* The set of allowed sort fields (columns) to sanitize the URL query parameter "sortField".
*
* @return the set of allowed sort fields (columns)
*/
@Override
protected Set<String> getAllowedSortFields() {
return Set.of("title", "type");
}

}
44 changes: 44 additions & 0 deletions Kitodo/src/main/java/org/kitodo/production/forms/BaseEditView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* (c) Kitodo. Key to digital objects e. V. <[email protected]>
*
* This file is part of the Kitodo project.
*
* It is licensed under GNU General Public License version 3 or later.
*
* For the full copyright and license information, please read the
* GPL3-License.txt file that was distributed with this source code.
*/

package org.kitodo.production.forms;

/**
* Base class for an edit view.
*
* <p>Manages the view state, e.g. forwarded list view options via URL query parameters.</p>
*
* <p>(BaseForm methods specific to edit views should be moved here in the future)</p>
*/
public class BaseEditView extends BaseForm {

protected String referrerListOptions;

/**
* Return the list options (URL query parameters) that were used while browsing a list before navigating to an edit view.
*
* @return the referrer list view options (URL query parameters)
*/
public String getReferrerListOptions() {
return referrerListOptions;
}

/**
* Set the list options (URL query parameters) that were used while browsing a list before navigating to an edit view.
*
* @param referrerListOptions the referrer list options (URL query parameters)
*/
public void setReferrerListOptionsFromTemplate(String referrerListOptions) {
this.referrerListOptions = referrerListOptions;
}


}
30 changes: 27 additions & 3 deletions Kitodo/src/main/java/org/kitodo/production/forms/BaseForm.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.kitodo.production.services.ServiceManager;
import org.kitodo.production.services.data.ClientService;
import org.kitodo.production.services.data.RoleService;
import org.primefaces.PrimeFaces;
import org.primefaces.component.datatable.DataTable;
import org.primefaces.event.TabChangeEvent;
import org.primefaces.event.data.PageEvent;
Expand Down Expand Up @@ -101,11 +102,27 @@ public void setFirstRow(int firstRow) {
}

/**
* Update first row to show in datatable on PageEvent.
* Set first row from the view parameter (query parameter), which might be unavailable or an arbitrary value.
*/
public void setFirstRowFromTemplate(String firstRow) {
if (Objects.nonNull(firstRow) && !firstRow.isEmpty()) {
try {
this.firstRow = Integer.parseInt(firstRow);
} catch (NumberFormatException e) {
this.firstRow = 0;
}
}
}

/**
* Event listener in case a user navigates to a different page in the list view.
*
* @param pageEvent PageEvent triggered by data tables paginator
*/
public void onPageChange(PageEvent pageEvent) {
this.setFirstRow(((DataTable) pageEvent.getSource()).getFirst());
DataTable source = (DataTable) pageEvent.getSource();
String script = "kitodo.updateQueryParameter('firstRow', '" + source.getRows() * pageEvent.getPage() + "');";
PrimeFaces.current().executeScript(script);
}

/**
Expand Down Expand Up @@ -172,7 +189,14 @@ public void setStayOnCurrentPage(String stayOnCurrentPage) {
*/
public User getUser() {
if (Objects.isNull(this.user)) {
this.user = ServiceManager.getUserService().getCurrentUser();
try {
User authenticatedUser = ServiceManager.getUserService().getCurrentUser();
// reload user from database, since authenticated user object might contain outdated data,
// e.g. outdated filters
this.user = ServiceManager.getUserService().getById(authenticatedUser.getId());
} catch (DAOException e) {
Helper.setErrorMessage(ERROR_LOADING_ONE, ObjectType.USER.getTranslationSingular(), getUser().getId());
}
}
return this.user;
}
Expand Down
Loading
Loading