Management of roles for Content Sections

Former-commit-id: 7507a3032162f8df0d09cc511afaf873d4785780
pull/10/head
Jens Pelzetter 2021-02-24 21:45:05 +01:00
parent 99d13efbde
commit f22e00b166
6 changed files with 958 additions and 53 deletions

View File

@ -10,9 +10,13 @@ import org.libreccm.api.IdentifierParser;
import org.libreccm.core.CcmObject;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.Party;
import org.libreccm.security.PartyRepository;
import org.libreccm.security.Permission;
import org.libreccm.security.PermissionChecker;
import org.libreccm.security.PermissionManager;
import org.libreccm.security.Role;
import org.libreccm.security.RoleManager;
import org.libreccm.security.RoleMembership;
import org.libreccm.security.RoleRepository;
@ -32,6 +36,8 @@ import org.librecms.contentsection.ContentSectionManager;
import org.librecms.contentsection.ContentSectionRepository;
import org.librecms.contentsection.Folder;
import org.librecms.contentsection.privileges.AdminPrivileges;
import org.librecms.contentsection.privileges.AssetPrivileges;
import org.librecms.contentsection.privileges.ItemPrivileges;
import org.librecms.ui.CmsAdminMessages;
import java.util.ArrayList;
@ -40,7 +46,6 @@ import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
@ -74,9 +79,18 @@ public class ConfigurationRolesController {
@Inject
private Models models;
@Inject
private PartyRepository partyRepository;
@Inject
private PermissionChecker permissionChecker;
@Inject
private PermissionManager permissionManager;
@Inject
private RoleManager roleManager;
@Inject
private RoleRepository roleRepo;
@ -238,18 +252,7 @@ public class ConfigurationRolesController {
.collect(Collectors.toList())
);
selectedRoleModel.setName(role.getName());
selectedRoleModel.setPermissions(
role
.getPermissions()
.stream()
.filter(
permission -> onlyContentSectionPermissions(
permission, section
)
)
.map(permission -> permission.getGrantedPrivilege())
.collect(Collectors.toList())
);
selectedRoleModel.setPermissions(buildRolePermissions(role, section));
final Set<Locale> descriptionLocales = role
.getDescription()
.getAvailableLocales();
@ -266,6 +269,495 @@ public class ConfigurationRolesController {
return "org/librecms/ui/contentsection/configuration/role.xhtml";
}
@POST
@Path("/{roleName}/@rename")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String renameRole(
@PathParam("sectionIdentifier") final String sectionIdentifierParam,
@PathParam("roleName") final String roleName,
@FormParam("roleName") final String newRoleName
) {
final Identifier sectionIdentifier = identifierParser.parseIdentifier(
sectionIdentifierParam
);
final Optional<ContentSection> sectionResult;
switch (sectionIdentifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(
sectionIdentifier.getIdentifier()
)
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(
sectionIdentifier.getIdentifier()
);
break;
default:
sectionResult = sectionRepo.findByLabel(
sectionIdentifier.getIdentifier()
);
break;
}
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
final ContentSection section = sectionResult.get();
sectionModel.setSection(section);
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_ROLES, section
)) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Optional<Role> result = section
.getRoles()
.stream()
.filter(role -> roleName.equals(role.getName()))
.findAny();
if (!result.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("roleName", roleName);
return "org/librecms/ui/contentsection/configuration/role-not-found.xhtml";
}
final Role role = result.get();
role.setName(newRoleName);
roleRepo.save(role);
return String.format(
"redirect:%s/configuration/roles/%s",
sectionIdentifierParam,
newRoleName
);
}
@POST
@Path("/{roleName}/@permissions")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateRolePermissions(
@PathParam("sectionIdentifier") final String sectionIdentifierParam,
@PathParam("roleName") final String roleName,
@FormParam("grantedPermissions") final List<String> grantedPermissions
) {
final Identifier sectionIdentifier = identifierParser.parseIdentifier(
sectionIdentifierParam
);
final Optional<ContentSection> sectionResult;
switch (sectionIdentifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(
sectionIdentifier.getIdentifier()
)
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(
sectionIdentifier.getIdentifier()
);
break;
default:
sectionResult = sectionRepo.findByLabel(
sectionIdentifier.getIdentifier()
);
break;
}
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
final ContentSection section = sectionResult.get();
sectionModel.setSection(section);
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_ROLES, section
)) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Optional<Role> result = section
.getRoles()
.stream()
.filter(role -> roleName.equals(role.getName()))
.findAny();
if (!result.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("roleName", roleName);
return "org/librecms/ui/contentsection/configuration/role-not-found.xhtml";
}
final Role role = result.get();
for (final String privilege : permissionManager.listDefiniedPrivileges(
AdminPrivileges.class
)) {
if (grantedPermissions.contains(privilege)) {
permissionManager.grantPrivilege(privilege, role, section);
} else {
permissionManager.revokePrivilege(privilege, role, section);
}
}
final Folder documentsFolder = section.getRootDocumentsFolder();
for (final String privilege : permissionManager.listDefiniedPrivileges(
ItemPrivileges.class
)) {
if (grantedPermissions.contains(privilege)) {
permissionManager.grantPrivilege(
privilege, role, documentsFolder
);
} else {
permissionManager.revokePrivilege(
privilege, role, documentsFolder
);
}
}
final Folder assetsFolder = section.getRootAssetsFolder();
for (final String privilege : permissionManager.listDefiniedPrivileges(
AssetPrivileges.class
)) {
if (grantedPermissions.contains(privilege)) {
permissionManager.grantPrivilege(
privilege, role, assetsFolder
);
} else {
permissionManager.revokePrivilege(
privilege, role, assetsFolder
);
}
}
return String.format(
"redirect:%s/configuration/roles/%s",
sectionIdentifierParam,
roleName
);
}
@POST
@Path("/{roleName}/@members")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String updateRoleMembers(
@PathParam("sectionIdentifier") final String sectionIdentifierParam,
@PathParam("roleName") final String roleName,
@FormParam("roleMembers") final List<String> roleMembersParam
) {
final Identifier sectionIdentifier = identifierParser.parseIdentifier(
sectionIdentifierParam
);
final Optional<ContentSection> sectionResult;
switch (sectionIdentifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(
sectionIdentifier.getIdentifier()
)
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(
sectionIdentifier.getIdentifier()
);
break;
default:
sectionResult = sectionRepo.findByLabel(
sectionIdentifier.getIdentifier()
);
break;
}
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
final ContentSection section = sectionResult.get();
sectionModel.setSection(section);
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_ROLES, section
)) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Optional<Role> result = section
.getRoles()
.stream()
.filter(role -> roleName.equals(role.getName()))
.findAny();
if (!result.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("roleName", roleName);
return "org/librecms/ui/contentsection/configuration/role-not-found.xhtml";
}
final Role role = result.get();
// Check for new members
final List<String> newMemberNames = roleMembersParam
.stream()
.filter(memberName -> !hasMember(role, memberName))
.collect(Collectors.toList());
// Check for removed members
final List<String> removedMemberNames = role
.getMemberships()
.stream()
.map(membership -> membership.getMember().getName())
.filter(memberName -> !roleMembersParam.contains(memberName))
.collect(Collectors.toList());
for (final String newMemberName : newMemberNames) {
addNewMember(role, newMemberName);
}
for (final String removedMemberName : removedMemberNames) {
removeMember(role, removedMemberName);
}
return String.format(
"redirect:%s/configuration/roles/%s",
sectionIdentifierParam,
roleName
);
}
@POST
@Path("/{roleName}/description/@add")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String addDescription(
@PathParam("sectionIdentifier") final String sectionIdentifierParam,
@PathParam("roleName") final String roleName,
@FormParam("locale") final String localeParam,
@FormParam("value") final String value
) {
final Identifier sectionIdentifier = identifierParser.parseIdentifier(
sectionIdentifierParam
);
final Optional<ContentSection> sectionResult;
switch (sectionIdentifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(
sectionIdentifier.getIdentifier()
)
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(
sectionIdentifier.getIdentifier()
);
break;
default:
sectionResult = sectionRepo.findByLabel(
sectionIdentifier.getIdentifier()
);
break;
}
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
final ContentSection section = sectionResult.get();
sectionModel.setSection(section);
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_ROLES, section
)) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Optional<Role> result = section
.getRoles()
.stream()
.filter(role -> roleName.equals(role.getName()))
.findAny();
if (!result.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("roleName", roleName);
return "org/librecms/ui/contentsection/configuration/role-not-found.xhtml";
}
final Role role = result.get();
final Locale locale = new Locale(localeParam);
role.getDescription().addValue(locale, value);
roleRepo.save(role);
return String.format(
"redirect:%s/configuration/roles/%s",
sectionIdentifierParam,
roleName
);
}
@POST
@Path("/{roleName}/description/@edit/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String editDescription(
@PathParam("sectionIdentifier") final String sectionIdentifierParam,
@PathParam("roleName") final String roleName,
@PathParam("locale") final String localeParam,
@FormParam("value") final String value
) {
final Identifier sectionIdentifier = identifierParser.parseIdentifier(
sectionIdentifierParam
);
final Optional<ContentSection> sectionResult;
switch (sectionIdentifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(
sectionIdentifier.getIdentifier()
)
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(
sectionIdentifier.getIdentifier()
);
break;
default:
sectionResult = sectionRepo.findByLabel(
sectionIdentifier.getIdentifier()
);
break;
}
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
final ContentSection section = sectionResult.get();
sectionModel.setSection(section);
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_ROLES, section
)) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Optional<Role> result = section
.getRoles()
.stream()
.filter(role -> roleName.equals(role.getName()))
.findAny();
if (!result.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("roleName", roleName);
return "org/librecms/ui/contentsection/configuration/role-not-found.xhtml";
}
final Role role = result.get();
final Locale locale = new Locale(localeParam);
role.getDescription().addValue(locale, value);
roleRepo.save(role);
return String.format(
"redirect:%s/configuration/roles/%s",
sectionIdentifierParam,
roleName
);
}
@POST
@Path("/{roleName}/description/@remove/{locale}")
@AuthorizationRequired
@Transactional(Transactional.TxType.REQUIRED)
public String removeDescription(
@PathParam("sectionIdentifier") final String sectionIdentifierParam,
@PathParam("roleName") final String roleName,
@PathParam("locale") final String localeParam,
@FormParam("value") final String value
) {
final Identifier sectionIdentifier = identifierParser.parseIdentifier(
sectionIdentifierParam
);
final Optional<ContentSection> sectionResult;
switch (sectionIdentifier.getType()) {
case ID:
sectionResult = sectionRepo.findById(
Long.parseLong(
sectionIdentifier.getIdentifier()
)
);
break;
case UUID:
sectionResult = sectionRepo.findByUuid(
sectionIdentifier.getIdentifier()
);
break;
default:
sectionResult = sectionRepo.findByLabel(
sectionIdentifier.getIdentifier()
);
break;
}
if (!sectionResult.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/contentsection-not-found.xhtml";
}
final ContentSection section = sectionResult.get();
sectionModel.setSection(section);
if (!permissionChecker.isPermitted(
AdminPrivileges.ADMINISTER_ROLES, section
)) {
models.put("sectionIdentifier", sectionIdentifier);
return "org/librecms/ui/contentsection/access-denied.xhtml";
}
final Optional<Role> result = section
.getRoles()
.stream()
.filter(role -> roleName.equals(role.getName()))
.findAny();
if (!result.isPresent()) {
models.put("sectionIdentifier", sectionIdentifier);
models.put("roleName", roleName);
return "org/librecms/ui/contentsection/configuration/role-not-found.xhtml";
}
final Role role = result.get();
final Locale locale = new Locale(localeParam);
role.getDescription().removeValue(locale);
return String.format(
"redirect:%s/configuration/roles/%s",
sectionIdentifierParam,
roleName
);
}
@POST
@Path("/@new")
@AuthorizationRequired
@ -603,4 +1095,94 @@ public class ConfigurationRolesController {
|| rootAssetsFolder.equals(object);
}
private List<RoleSectionPermissionModel> buildRolePermissions(
final Role role, final ContentSection section
) {
final List<RoleSectionPermissionModel> adminPermissions
= permissionManager
.listDefiniedPrivileges(AdminPrivileges.class)
.stream()
.map(
privilege -> buildRoleSectionPermissionModel(
role, privilege, section
)
).collect(Collectors.toList());
final List<RoleSectionPermissionModel> itemPermissions
= permissionManager
.listDefiniedPrivileges(ItemPrivileges.class)
.stream()
.map(
privilege -> buildRoleSectionPermissionModel(
role, privilege, section.getRootDocumentsFolder()
)
).collect(Collectors.toList());
final List<RoleSectionPermissionModel> assetPermissions
= permissionManager
.listDefiniedPrivileges(AssetPrivileges.class)
.stream()
.map(
privilege -> buildRoleSectionPermissionModel(
role, privilege, section.getRootAssetsFolder()
)
).collect(Collectors.toList());
final List<RoleSectionPermissionModel> permissions = new ArrayList<>();
permissions.addAll(adminPermissions);
permissions.addAll(itemPermissions);
permissions.addAll(assetPermissions);
return permissions;
}
private RoleSectionPermissionModel buildRoleSectionPermissionModel(
final Role role, final String privilege, final ContentSection section
) {
final RoleSectionPermissionModel model
= new RoleSectionPermissionModel();
model.setPrivilege(privilege);
model.setGranted(
permissionChecker.isPermitted(privilege, section, role)
);
return model;
}
private RoleSectionPermissionModel buildRoleSectionPermissionModel(
final Role role, final String privilege, final Folder folder
) {
final RoleSectionPermissionModel model
= new RoleSectionPermissionModel();
model.setPrivilege(privilege);
model.setGranted(
permissionChecker.isPermitted(privilege, folder, role)
);
return model;
}
private boolean hasMember(final Role role, final String memberName) {
return role
.getMemberships()
.stream()
.map(membership -> membership.getMember().getName())
.anyMatch(name -> name.equals(memberName));
}
private void addNewMember(final Role role, final String newMemberName) {
final Optional<Party> result = partyRepository.findByName(
newMemberName
);
if (result.isPresent()) {
final Party party = result.get();
roleManager.assignRoleToParty(role, party);
}
}
private void removeMember(final Role role, final String removedMemberName) {
final Optional<Party> result = partyRepository.findByName(
removedMemberName
);
if (result.isPresent()) {
final Party party = result.get();
roleManager.removeRoleFromParty(role, party);
}
}
}

View File

@ -0,0 +1,34 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.librecms.ui.contentsections;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class RoleSectionPermissionModel {
private String privilege;
private boolean granted;
public String getPrivilege() {
return privilege;
}
public void setPrivilege(final String privilege) {
this.privilege = privilege;
}
public boolean isGranted() {
return granted;
}
public void setGranted(final boolean granted) {
this.granted = granted;
}
}

View File

@ -5,13 +5,19 @@
*/
package org.librecms.ui.contentsections;
import org.libreccm.security.Party;
import org.libreccm.security.PartyRepository;
import org.libreccm.ui.admin.usersgroupsroles.RolePartyFormEntry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
/**
@ -22,20 +28,29 @@ import javax.inject.Named;
@Named("SelectedRoleModel")
public class SelectedRoleModel {
@Inject
private PartyRepository partyRepository;
private String name;
private Map<String, String> description;
private List<String> unusedDescriptionLocales;
private List<RoleMembershipModel> members;
public List<RolePartyFormEntry> getRolePartyFormEnties() {
return partyRepository
.findAll()
.stream()
.map(this::buildRolePartyFormEntry)
.collect(Collectors.toList());
}
/**
* Permissions of the role for the content section.
*/
private List<String> permissions;
private List<RoleSectionPermissionModel> permissions;
public String getName() {
return name;
@ -61,11 +76,12 @@ public class SelectedRoleModel {
this.members = new ArrayList<>(members);
}
public List<String> getPermissions() {
public List<RoleSectionPermissionModel> getPermissions() {
return Collections.unmodifiableList(permissions);
}
public void setPermissions(final List<String> permissions) {
public void setPermissions(
final List<RoleSectionPermissionModel> permissions) {
this.permissions = new ArrayList<>(permissions);
}
@ -83,5 +99,21 @@ public class SelectedRoleModel {
public boolean getHasUnusedDescriptionLocales() {
return !unusedDescriptionLocales.isEmpty();
}
private RolePartyFormEntry buildRolePartyFormEntry(final Party party) {
final RolePartyFormEntry entry = new RolePartyFormEntry();
entry.setPartyId(party.getPartyId());
entry.setPartyUuid(party.getUuid());
entry.setPartyName(party.getName());
entry.setMember(
members
.stream()
.anyMatch(
membership -> membership.getMemberUuid().equals(party
.getUuid())
)
);
return entry;
}
}

View File

@ -39,22 +39,76 @@
<dd>
#{SelectedRoleModel.name}
<button class="btn btn-info btn-sm"
data-target="#edit-role-name-dialog"
data-toggle="modal"
type="button">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">#{CmsAdminMessages['contentsection.configuration.roles.role_details.name.edit']}</span>
</button>
<div aria-hidden="true"
aria-labelledby="edit-role-name-dialog-title"
class="modal fade"
id="edit-role-name-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/@rename"
class="modal-content"
method="post">
<div class="modal-header">
<h2 class="modal-title"
id="edit-role-name-dialog">
#{CmsAdminMessages.getMessage("contentsection.configuration.roles.role_details.name.edit.dialog.title", [SelectedRoleModel.name])}
<button aria-label="#{CmsAdminMessages['contentsection.configuration.roles.role_details.name.edit.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</h2>
</div>
<div class="modal-body">
<bootstrap:formGroupText
help="#{CmsAdminMessages['contentsection.configuration.roles.role_details.name.edit.dialog.name.help']}"
inputId="roleName"
label="#{CmsAdminMessages['contentsection.configuration.roles.role_details.name.edit.dialog.name.label']}"
name="roleName"
pattern="[a-zA-Z0-9_-]*"
required="required"
value="#{SelectedRoleModel.name}"/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.name.edit.dialog.close']}
</button>
<button class="btn btn-success"
type="submit">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.name.edit.dialog.submit']}
</button>
</div>
</form>
</div>
</div>
</dd>
</div>
</dl>
<libreccm:localizedStringEditor
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/description/add"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/description/edit"
addDialogCancelLabel="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.add.cancel']}"
addDialogSubmitLabel="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.add.submit']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/description/@add"
editDialogCancelLabel="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.edit.cancel']}"
editDialogSubmitLabel="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.edit.submit']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/description/@edit"
editorId="role-description"
hasUnusedLocales="#{SelectedRoleModel.hasUnusedDescriptionLocales}"
objectIdentifier="#{SelectedRoleModel.name}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/description/remove"
removeDialogCancelLabel="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.remove.cancel']}"
removeDialogSubmitLabel="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.remove.submit']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/description/@remove"
title="#{CmsAdminMessages['contentsection.configuration.roles.role_details.description.title']}"
unusedLocales="#{SelectedRoleModel.unusedDescriptionLocales}"
useTextarea="true"
values="#{SelectedRoleModel.description}"
/>
@ -69,16 +123,102 @@
<span>#{CmsAdminMessages['contentsection.configuration.role_details.permissions.modify']}</span>
</button>
</div>
<div aria-hidden="true"
aria-labelledby="modify-permisisons-dialog-title"
class="modal fade"
id="modify-permissions-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/@permissions"
class="modal-content"
method="post">
<div class="modal-header">
<h3 class="modal-title"
id="modify-permissions-dialog-title">
#{CmsAdminMessages.getMessage('contentsection.configuration.role_details.permissions.modify.dialog.title', [SelectedRoleModel.name])}
</h3>
<button aria-label="#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.modify.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-body">
<c:forEach items="#{SelectedRoleModel.permissions}"
var="permission">
<div class="form-check">
<input checked="#{permission.granted ? 'checked' : ''}"
class="form-check-input"
id="#{permission.privilege}"
name="grantedPermissions"
value="#{permission.privilege}"
type="checkbox" />
<label class="form-check-label"
for="#{permission.privilege}">
#{CmsAdminMessages['contentsection.privileges.'.concat(permission.privilege)]}
</label>
</div>
</c:forEach>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.modify.dialog.close']}
</button>
<button class="btn btn-success"
type="submit">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.modify.dialog.submit']}
</button>
</div>
</form>
</div>
</div>
</div>
<ul>
<table>
<thead>
<tr>
<th scope="col">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.table.privilege']}
</th>
<th scope="col">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.table.status']}
</th>
</tr>
</thead>
<c:forEach items="#{SelectedRoleModel.permissions}"
var="permission">
<li>
#{permission}
</li>
<tr>
<td>
#{CmsAdminMessages['contentsection.privileges.'.concat(permission.privilege)]}
</td>
<td>
<c:choose>
<c:when test="#{permission.granted}">
<div class="font-weight-bold text-success">
<bootstrap:svgIcon class="text-success"
icon="check" />
<span class="sr-only">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.table.status.granted']}
</span>
</div>
</c:when>
<c:otherwise>
<div class="font-weight-bold text-danger">
<bootstrap:svgIcon class="text-danger"
icon="x" />
<span class="sr-only">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.permissions.table.status.denied']}
</span>
</div>
</c:otherwise>
</c:choose>
</td>
</tr>
</c:forEach>
</ul>
</table>
<h2>#{CmsAdminMessages['contentsection.configuration.roles.role_details.members']}</h2>
<div class="mb-2">
<div class="text-right">
@ -89,33 +229,66 @@
<bootstrap:svgIcon icon="plus-circle" />
<span>#{CmsAdminMessages['contentsection.configuration.role_details.members.add']}</span>
</button>
<div aria-hidden="true"
aria-labelledby="add-member-dialog-title"
class="modal fade"
id="add-member-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/@members"
class="modal-content"
method="post">
<div class="modal-header">
<h3 class="modal-title"
id="add-member-dialog-title">
#{CmsAdminMessages.getMessage('contentsection.configuration.role_details.members.dialog.title', [SelectedRoleModel.name])}
</h3>
<button aria-label="#{CmsAdminMessages['contentsection.configuration.roles.role_details.members.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-content">
<c:forEach items="#{SelectedRoleModel.rolePartyFormEnties}"
var="entry">
<div class="form-check form-check-inline">
<input class="form-check-input"
checked="#{entry.member ? 'checked' : ''}"
id="party-#{entry.partyName}"
name="roleMembers"
value="#{entry.partyName}"
type="checkbox" />
<label class="form-check-label"
for="party-#{entry.partyName}">
#{entry.partyName}
</label>
</div>
</c:forEach>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.members.dialog.close']}
</button>
<button class="btn btn-success"
type="submit">
#{CmsAdminMessages['contentsection.configuration.roles.role_details.members.dialog.submit']}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<table class="table table-hover">
<thead>
<tr>
<th>#{CmsAdminMessages['contentsection.configuration.role_details.members.cols.name']}</th>
<th>#{CmsAdminMessages['contentsection.configuration.role_details.members.cols.actions']}</th>
</tr>
</thead>
<tbody>
<c:forEach items="#{SelectedRoleModel.members}"
var="member">
<tr>
<td>#{member.memberName}</td>
<td>
<libreccm:deleteDialog actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/roles/#{SelectedRoleModel.name}/members/#{member.memberUuid}"
buttonText="#{CmsAdminMessages['contentsection.configuration.role_details.members.actions.remove']}"
cancelLabel="#{CmsAdminMessages['contentsection.configuration.role_details.members.actions.remove.cancel']}"
confirmLabel="#{CmsAdminMessages['contentsection.configuration.role_details.members.actions.remove.confirm']}"
dialogId="remove-member-dialog"
dialogTitle="#{CmsAdminMessages['contentsection.configuration.role_details.members.actions.remove.title']}"
message="#{CmsAdminMessages.getMessage('contentsection.configuration.role_details.members.actions.remove.message', [member.memberName, SelectedRoleModel.name])}" />
</td>
</tr>
</c:forEach>
</tbody>
</table>
<ul>
<c:forEach items="#{SelectedRoleModel.members}"
var="member">
<li>#{member.memberName}</li>
</c:forEach>
</ul>
</div>
</ui:define>
</ui:composition>

View File

@ -327,3 +327,45 @@ contentsection.configuration.roles.table.actions.delete.cancel=Cancel
contentsection.configuration.roles.table.actions.delete.submit=Delete role
contentsection.configuration.roles.table.actions.delete.title=Confirm role deletion
contentsection.configuration.roles.table.actions.delete.message=Are you sure to remove role {0} from content section {1} and delete it?
contentsection.configuration.roles.role_details.name.edit.dialog.title=Rename role {0}
contentsection.configuration.roles.role_details.name.edit.dialog.close=Cancel
contentsection.configuration.roles.role_details.name.edit.dialog.name.help=The new name of the role. May only contain the letters a to z, A to Z, numbers, the underscore and the dash.
contentsection.configuration.roles.role_details.name.edit.dialog.name.label=Name
contentsection.configuration.roles.role_details.name.edit.dialog.submit=Rename role
contentsection.configuration.role_details.permissions.modify.dialog.title=Modify permissions of role {0}
contentsection.configuration.roles.role_details.permissions.modify.dialog.close=Cancel
contentsection.privileges.administer_categories=Administer categories
contentsection.privileges.administer_content_types=Administer content types
contentsection.privileges.administer_lifecyles=Administer lifecycles
contentsection.privileges.administer_roles=Administer roles
contentsection.privileges.administer_workflow=Administer workflows
contentsection.privileges.create_new_assets=Create new assets
contentsection.privileges.delete_assets=Delete assets
contentsection.privileges.use_asset=Use asset
contentsection.privileges.edit_asset=Edit assets
contentsection.privileges.view_asset=View assets
contentsection.privileges.administer_items=Administer items
contentsection.privileges.approve_items=Approve items
contentsection.privileges.categorize_items=Categorize items
contentsection.privileges.create_new_items=Create new items
contentsection.privileges.delete_items=Delete items
contentsection.privileges.edit_items=Edit items
contentsection.privileges.preview_items=Preview items
contentsection.privileges.publish_items=Publish items
contentsection.privileges.view_published_items=View published items
contentsection.privileges.use_type=Use type
contentsection.configuration.roles.role_details.permissions.modify.dialog.submit=Modify permissions
contentsection.configuration.role_details.members.dialog.title=Manage members for role {0}
contentsection.configuration.roles.role_details.members.dialog.close=Cancel
contentsection.configuration.roles.role_details.members.dialog.submit=Apply
contentsection.privileges.apply_alternate_workflow=Apply alternate workflow
contentsection.configuration.roles.role_details.permissions.table.privilege=Privilege
contentsection.configuration.roles.role_details.permissions.table.status=Status
contentsection.configuration.roles.role_details.permissions.table.status.denied=Not granted
contentsection.configuration.roles.role_details.permissions.table.status.granted=Gew\u00e4hrt
contentsection.configuration.roles.role_details.description.add.cancel=Cancel
contentsection.configuration.roles.role_details.description.add.submit=Add description
contentsection.configuration.roles.role_details.description.edit.cancel=Cancel
contentsection.configuration.roles.role_details.description.remove.cancel=Cancel
contentsection.configuration.roles.role_details.description.edit.submit=Save
contentsection.configuration.roles.role_details.description.remove.submit=Remove

View File

@ -328,3 +328,45 @@ contentsection.configuration.roles.table.actions.delete.cancel=Abbrechen
contentsection.configuration.roles.table.actions.delete.submit=Rolle l\u00f6schen
contentsection.configuration.roles.table.actions.delete.title=Confirm role deletion
contentsection.configuration.roles.table.actions.delete.message=Sind Sie sicher, dass die die Rolle {0} aus der Content Section {1} entfernen und l\u00f6schen wollen?
contentsection.configuration.roles.role_details.name.edit.dialog.title=Rolle {0} umbenennen
contentsection.configuration.roles.role_details.name.edit.dialog.close=Abbrechen
contentsection.configuration.roles.role_details.name.edit.dialog.name.help=Der neue Name der Rolle. Der Name einer Rolle darf nur die Buchstaben a bis z, A bis Z, Ziffern, den Unterstrich und den Bindestrich enthalten.
contentsection.configuration.roles.role_details.name.edit.dialog.name.label=Name
contentsection.configuration.roles.role_details.name.edit.dialog.submit=Rolle umbenennen
contentsection.configuration.role_details.permissions.modify.dialog.title=Berechtigungen der Rolle {0} anpassen
contentsection.configuration.roles.role_details.permissions.modify.dialog.close=Abbrechen
contentsection.privileges.administer_categories=Kategorien verwalten
contentsection.privileges.administer_content_types=Dokumenttypen verwalten
contentsection.privileges.administer_lifecyles=Lebenszyklen verwalten
contentsection.privileges.administer_roles=Rollen verwalten
contentsection.privileges.administer_workflow=Arbeitsabl\u00e4ufe verwalten
contentsection.privileges.create_new_assets=Neue Assets anlegen
contentsection.privileges.delete_assets=Assets l\u00f6schen
contentsection.privileges.use_asset=Assets verwenden
contentsection.privileges.edit_asset=Assets bearbeiten
contentsection.privileges.view_asset=Assets betrachten
contentsection.privileges.administer_items=Content Items verwalten
contentsection.privileges.approve_items=Inhalte freigeben
contentsection.privileges.categorize_items=Inhalte kategorisieren
contentsection.privileges.create_new_items=Inhalte erstellen
contentsection.privileges.delete_items=Inhalte l\u00f6schen
contentsection.privileges.edit_items=Inhalte bearbeiten
contentsection.privileges.preview_items=Vorschau von Inhalten ansehen
contentsection.privileges.publish_items=Inhalte ver\u00f6ffentlichen
contentsection.privileges.view_published_items=Ver\u00f6ffentlichte Inhalte ansehen
contentsection.privileges.use_type=Dokumenttyp verwenden
contentsection.configuration.roles.role_details.permissions.modify.dialog.submit=Berechtigungen anpassen
contentsection.configuration.role_details.members.dialog.title=Mitglieder der Rolle {0} verwalten
contentsection.configuration.roles.role_details.members.dialog.close=Abbrechen
contentsection.configuration.roles.role_details.members.dialog.submit=Anwenden
contentsection.privileges.apply_alternate_workflow=Alternativen Arbeitsablauf anwenden
contentsection.configuration.roles.role_details.permissions.table.privilege=Berechtigung
contentsection.configuration.roles.role_details.permissions.table.status=Status
contentsection.configuration.roles.role_details.permissions.table.status.denied=Nicht gew\u00e4hrt
contentsection.configuration.roles.role_details.permissions.table.status.granted=Gew\u00e4hrt
contentsection.configuration.roles.role_details.description.add.cancel=Abbrechen
contentsection.configuration.roles.role_details.description.add.submit=Bechreibung hinzuf\u00fcgen
contentsection.configuration.roles.role_details.description.edit.cancel=Abbrechen
contentsection.configuration.roles.role_details.description.remove.cancel=Abbrechen
contentsection.configuration.roles.role_details.description.edit.submit=Speichern
contentsection.configuration.roles.role_details.description.remove.submit=Entfernen