diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java
index ca4efdff9..225dff85e 100644
--- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java
+++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RoleAdmin.java
@@ -46,6 +46,7 @@ public class RoleAdmin extends BoxPanel {
private final BoxPanel roleMembersPanel;
private final RoleAddMemberForm roleAddMemberForm;
private final BoxPanel rolePermissionsPanel;
+ private final RolePermissionsForm rolePermissionsForm;
public RoleAdmin() {
super(BoxPanel.VERTICAL);
@@ -116,7 +117,10 @@ public class RoleAdmin extends BoxPanel {
final Label rolePermissionsHeading = new Label(new GlobalizedMessage(
"ui.admin.role_permissions.heading",
ADMIN_BUNDLE));
+ rolePermissionsHeading.setClassAttr("heading");
rolePermissionsPanel.add(rolePermissionsHeading);
+ rolePermissionsPanel.add(new Label(new GlobalizedMessage(
+ "ui.admin.role_permissions.note", ADMIN_BUNDLE)));
rolePermissionsPanel.add(new RolePermissionsTable(selectedRoleId));
final ActionLink addRolePermission = new ActionLink(
new GlobalizedMessage(
@@ -126,6 +130,9 @@ public class RoleAdmin extends BoxPanel {
});
rolePermissionsPanel.add(addRolePermission);
add(rolePermissionsPanel);
+
+ rolePermissionsForm = new RolePermissionsForm(this, selectedRoleId);
+ add(rolePermissionsForm);
}
@Override
@@ -140,6 +147,7 @@ public class RoleAdmin extends BoxPanel {
page.setVisibleDefault(roleMembersPanel, false);
page.setVisibleDefault(roleAddMemberForm, false);
page.setVisibleDefault(rolePermissionsPanel, false);
+ page.setVisibleDefault(rolePermissionsForm, false);
}
protected void showRoleDetails(final PageState state) {
@@ -149,6 +157,7 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, true);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
protected void hideRoleDetails(final PageState state) {
@@ -160,6 +169,7 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, false);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
protected void showRoleForm(final PageState state) {
@@ -169,6 +179,7 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, false);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
protected void hideRoleForm(final PageState state) {
@@ -182,6 +193,7 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, roleSelected);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
protected void showRoleMemberAddForm(final PageState state) {
@@ -191,17 +203,19 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, false);
roleAddMemberForm.setVisible(state, true);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
-
+
protected void showRoleMembersPanel(final PageState state) {
- rolesTablePanel.setVisible(state, false);
+ rolesTablePanel.setVisible(state, false);
roleForm.setVisible(state, false);
roleDetails.setVisible(state, true);
roleMembersPanel.setVisible(state, true);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
-
+
protected void hideRoleMemberAddForm(final PageState state) {
rolesTablePanel.setVisible(state, false);
roleForm.setVisible(state, false);
@@ -209,6 +223,7 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, true);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, false);
}
protected void showRolePermissionsPanel(final PageState state) {
@@ -218,6 +233,7 @@ public class RoleAdmin extends BoxPanel {
roleMembersPanel.setVisible(state, false);
roleAddMemberForm.setVisible(state, false);
rolePermissionsPanel.setVisible(state, true);
+ rolePermissionsForm.setVisible(state, false);
}
// protected void hideRolePermissionsPanel(final PageState state) {
@@ -228,13 +244,24 @@ public class RoleAdmin extends BoxPanel {
// roleAddMemberForm.setVisible(state, false);
// rolePermissionsPanel.setVisible(state, false);
// }
-
protected void showRolePermissionAddForm(final PageState state) {
-
+ rolesTablePanel.setVisible(state, false);
+ roleForm.setVisible(state, false);
+ roleDetails.setVisible(state, false);
+ roleMembersPanel.setVisible(state, false);
+ roleAddMemberForm.setVisible(state, false);
+ rolePermissionsPanel.setVisible(state, false);
+ rolePermissionsForm.setVisible(state, true);
}
protected void hideRolePermissionAddForm(final PageState state) {
-
+ rolesTablePanel.setVisible(state, false);
+ roleForm.setVisible(state, false);
+ roleDetails.setVisible(state, true);
+ roleMembersPanel.setVisible(state, false);
+ roleAddMemberForm.setVisible(state, false);
+ rolePermissionsPanel.setVisible(state, true);
+ rolePermissionsForm.setVisible(state, false);
}
}
diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsForm.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsForm.java
new file mode 100644
index 000000000..17a745b83
--- /dev/null
+++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsForm.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package com.arsdigita.ui.admin.usersgroupsroles.roles;
+
+import com.arsdigita.bebop.ActionLink;
+import com.arsdigita.bebop.Form;
+import com.arsdigita.bebop.FormData;
+import com.arsdigita.bebop.Label;
+import com.arsdigita.bebop.PageState;
+import com.arsdigita.bebop.ParameterSingleSelectionModel;
+import com.arsdigita.bebop.SaveCancelSection;
+import com.arsdigita.bebop.form.TextField;
+import com.arsdigita.globalization.GlobalizedMessage;
+
+import org.libreccm.cdi.utils.CdiUtil;
+import org.libreccm.core.CcmObject;
+import org.libreccm.core.CcmObjectRepository;
+import org.libreccm.security.PermissionManager;
+import org.libreccm.security.Role;
+import org.libreccm.security.RoleRepository;
+
+import static com.arsdigita.ui.admin.AdminUiConstants.*;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class RolePermissionsForm extends Form {
+
+ private static final String OBJECT_ID = "objectId";
+ private static final String PRIVILEGE = "privilege";
+
+ private final TextField objectId;
+ private final TextField privilege;
+ private final SaveCancelSection saveCancelSection;
+
+ public RolePermissionsForm(
+ final RoleAdmin roleAdmin,
+ final ParameterSingleSelectionModel selectedRoleId) {
+
+ super("rolePermissionsForm");
+
+ final ActionLink backToRole = new ActionLink(new GlobalizedMessage(
+ "ui.admin.group_details.add_permission.back",
+ ADMIN_BUNDLE));
+ backToRole.addActionListener(e -> {
+ roleAdmin.showRolePermissionsPanel(e.getPageState());
+ });
+ add(backToRole);
+
+ final Label heading = new Label();
+ heading.setClassAttr("heading");
+ heading.addPrintListener(e -> {
+ final PageState state = e.getPageState();
+ final Label target = (Label) e.getTarget();
+
+ final RoleRepository roleRepository = CdiUtil.createCdiUtil()
+ .findBean(RoleRepository.class);
+ final Role role = roleRepository.findById(Long.parseLong(
+ selectedRoleId.getSelectedKey(state)));
+
+ target.setLabel(new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.heading",
+ ADMIN_BUNDLE,
+ new String[]{role.getName()}));
+ });
+ add(heading);
+
+ objectId = new TextField(OBJECT_ID);
+ objectId.setLabel(new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.object_id.label",
+ ADMIN_BUNDLE));
+ objectId.setHint(new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.object_id.hint",
+ ADMIN_BUNDLE
+ ));
+ add(objectId);
+
+ privilege = new TextField(PRIVILEGE);
+ privilege.setLabel(new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.privilege.label",
+ ADMIN_BUNDLE));
+ privilege.setHint(new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.privilege.hint",
+ ADMIN_BUNDLE
+ ));
+ add(privilege);
+
+ saveCancelSection = new SaveCancelSection();
+ add(saveCancelSection);
+
+ addValidationListener(e -> {
+ final PageState state = e.getPageState();
+
+ if (saveCancelSection.getSaveButton().isSelected(state)) {
+ final FormData data = e.getFormData();
+
+ final String privilegeData = data.getString(PRIVILEGE);
+ if (privilegeData == null || privilegeData.isEmpty()) {
+ data.addError(PRIVILEGE, new GlobalizedMessage(
+ "ui.admin.role_details.add_permission."
+ + "privilege.error.notempty",
+ ADMIN_BUNDLE));
+ }
+
+ final String objectIdData = data.getString(OBJECT_ID);
+ if (objectIdData != null && !objectIdData.isEmpty()) {
+ final CcmObjectRepository objectRepository = CdiUtil
+ .createCdiUtil().findBean(CcmObjectRepository.class);
+
+ try {
+ Long.parseLong(objectIdData);
+ } catch (NumberFormatException ex) {
+ data.addError(
+ OBJECT_ID,
+ new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.object_id"
+ + ".error.nan",
+ ADMIN_BUNDLE));
+ return;
+ }
+
+ final CcmObject object = objectRepository.findObjectById(
+ Long.parseLong(objectIdData));
+ if (object == null) {
+ data.addError(
+ OBJECT_ID,
+ new GlobalizedMessage(
+ "ui.admin.role_details.add_permission.object_id"
+ + ".error.no_object",
+ ADMIN_BUNDLE));
+ }
+ }
+ }
+ });
+
+ addProcessListener(e -> {
+ final PageState state = e.getPageState();
+
+ if (saveCancelSection.getSaveButton().isSelected(state)) {
+ final FormData data = e.getFormData();
+
+ final String privilegeData = data.getString(PRIVILEGE);
+ final String objectIdData = data.getString(OBJECT_ID);
+
+ final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
+ final RoleRepository roleRepository = cdiUtil.findBean(
+ RoleRepository.class);
+
+ final Role role = roleRepository.findById(Long.parseLong(
+ selectedRoleId.getSelectedKey(state)));
+ final PermissionManager permissionManager = cdiUtil.findBean(
+ PermissionManager.class);
+ if (objectIdData == null || objectIdData.isEmpty()) {
+ permissionManager.grantPrivilege(privilegeData, role);
+ } else {
+ final CcmObjectRepository objectRepository = cdiUtil
+ .findBean(CcmObjectRepository.class);
+ final CcmObject object = objectRepository.findObjectById(
+ Long.parseLong(objectIdData));
+ permissionManager.grantPrivilege(privilegeData,
+ role,
+ object);
+ }
+ }
+
+ roleAdmin.showRolePermissionsPanel(state);
+ });
+ }
+
+}
diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java
index 5aabf0dfa..27c20a7c3 100644
--- a/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java
+++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/usersgroupsroles/roles/RolePermissionsTable.java
@@ -173,8 +173,9 @@ public class RolePermissionsTable extends Table {
final RoleRepository roleRepository = CdiUtil.createCdiUtil()
.findBean(RoleRepository.class);
- final Role role = roleRepository.findById(Long.parseLong(
- selectedRoleId.getSelectedKey(state)));
+ final Role role = roleRepository.findById(
+ Long.parseLong(selectedRoleId.getSelectedKey(state)),
+ Role.ENTITY_GRPAH_WITH_PERMISSIONS);
permissions = new ArrayList<>(role.getPermissions());
diff --git a/ccm-core/src/main/java/org/libreccm/core/CcmObject.java b/ccm-core/src/main/java/org/libreccm/core/CcmObject.java
index ba2740e1e..1c57923d7 100644
--- a/ccm-core/src/main/java/org/libreccm/core/CcmObject.java
+++ b/ccm-core/src/main/java/org/libreccm/core/CcmObject.java
@@ -39,6 +39,8 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
@@ -66,6 +68,10 @@ import javax.xml.bind.annotation.XmlRootElement;
@Entity
@Table(name = "CCM_OBJECTS", schema = DB_SCHEMA)
@Inheritance(strategy = InheritanceType.JOINED)
+@NamedQueries({
+ @NamedQuery(name = "CcmObject.findById",
+ query = "SELECT o FROM CcmObject o WHERE o.objectId = :id")
+})
@XmlRootElement(name = "ccm-object", namespace = CORE_XML_NS)
//False warning (?). Because this class has been migrated from the old PDL style
//persistence system we can't yet refactor it to make PMD happy. Also I think
diff --git a/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java b/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java
index 745ff2cc9..95b74983f 100644
--- a/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java
+++ b/ccm-core/src/main/java/org/libreccm/core/CcmObjectRepository.java
@@ -18,18 +18,17 @@
*/
package org.libreccm.core;
-
-
-
import static org.libreccm.core.CoreConstants.*;
import java.util.UUID;
import javax.enterprise.context.RequestScoped;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
/**
- * A repository class for {@link CcmObject}.
- *
+ * A repository class for {@link CcmObject}.
+ *
* @author Jens Pelzetter
*/
@RequestScoped
@@ -45,12 +44,12 @@ public class CcmObjectRepository extends AbstractEntityRepository query = getEntityManager().createNamedQuery(
+ "CcmObject.findById", CcmObject.class);
+ query.setParameter("id", objectId);
+
+ try {
+ return query.getSingleResult();
+ } catch (NoResultException ex) {
+ return null;
+ }
+ }
+
}
diff --git a/ccm-core/src/main/java/org/libreccm/security/Role.java b/ccm-core/src/main/java/org/libreccm/security/Role.java
index 994e093c5..14f3ec24d 100644
--- a/ccm-core/src/main/java/org/libreccm/security/Role.java
+++ b/ccm-core/src/main/java/org/libreccm/security/Role.java
@@ -65,23 +65,33 @@ import javax.xml.bind.annotation.XmlRootElement;
query = "SELECT r FROM Role r ORDER BY r.name"),
@NamedQuery(
name = "Role.searchByName",
- query = "SELECT r FROM Role r WHERE LOWER(r.name) LIKE CONCAT(LOWER(:name), '%') "
- + "ORDER BY r.name ")
+ query
+ = "SELECT r FROM Role r WHERE LOWER(r.name) LIKE CONCAT(LOWER(:name), '%') "
+ + "ORDER BY r.name ")
})
@NamedEntityGraphs({
@NamedEntityGraph(
- name = "Role.withMembers",
+ name = Role.ENTITY_GRPAH_WITH_MEMBERS,
attributeNodes = {
- @NamedAttributeNode(value = "memberships")
+ @NamedAttributeNode(value = "memberships"),}),
+ @NamedEntityGraph(
+ name = Role.ENTITY_GRPAH_WITH_PERMISSIONS,
+ attributeNodes = {
+ @NamedAttributeNode(value = "permissions")
})
})
-@DefaultEntityGraph("Role.withMembers")
+@DefaultEntityGraph(Role.ENTITY_GRPAH_WITH_MEMBERS)
@XmlRootElement(name = "role", namespace = CORE_XML_NS)
@SuppressWarnings({"PMD.ShortClassName", "PMD.TooManyMethods"})
public class Role implements Serializable {
private static final long serialVersionUID = -7121296514181469687L;
+ public static final String ENTITY_GRPAH_WITH_MEMBERS
+ = "Role.withMembers";
+ public static final String ENTITY_GRPAH_WITH_PERMISSIONS
+ = "Role.withPermissions";
+
@Id
@Column(name = "ROLE_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties
index 9d1b7e5b7..1f84ffc0a 100644
--- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties
+++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties
@@ -321,3 +321,14 @@ ui.admin.role_permissions.on_object=On object
ui.admin.role_permissions.revoke=Revoke
ui.admin.role_permissions.revoke.confirm=Are you sure to revoke this permission?
ui.admin.role_permissions.heading=Permissions
+ui.admin.role_permissions.add_permission=Add permission
+ui.admin.group_details.add_permission.back=Back to role properties
+ui.admin.role_details.add_permission.heading=Add permission to role {0}
+ui.admin.role_details.add_permission.object_id.label=Object id
+ui.admin.role_details.add_permission.object_id.hint=The id for which the new permission is granted. If left empty the permission is granted for all objects.
+ui.admin.role_details.add_permission.privilege.label=Privilege
+ui.admin.role_details.add_permission.privilege.hint=The privilege granted.
+ui.admin.role_permissions.note=Please note that this form only provides very basic facilities for managing permissions. Usually the specific applications provide a better UI for managing their specific permissions.
+ui.admin.role_details.add_permission.privilege.error.notempty=Privilege can't be empty.
+ui.admin.role_details.add_permission.object_id.error.nan=The provided value of object id is not an valid id.
+ui.admin.role_details.add_permission.object_id.error.no_object=There is no object with the provided id.
diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties
index bf0828fd4..b886c7cd0 100644
--- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties
+++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties
@@ -318,9 +318,20 @@ ui.admin.role_members.add.table.type=Typ
ui.admin.role_members.table.add=Hinzuf\u00fcgen
ui.admin.role_members.add=Mitglied hinzuf\u00fcgen
ui.admin.role_members.add.back=Zur\u00fcck zu den Eigenschaften der Rolle
-ui.admin.role_permissions.none=Dieser Rolle wurde keine Berechtigungen gew\u00e4hrt
+ui.admin.role_permissions.none=Dieser Rolle wurden keine Berechtigungen gew\u00e4hrt
ui.admin.role_permissions.privilege=Privileg
ui.admin.role_permissions.on_object=Auf Objekt
ui.admin.role_permissions.revoke=L\u00f6schen
ui.admin.role_permissions.revoke.confirm=Sind Sie sicher, dass Sie diese Berechtigung l\u00f6schen wollen?
ui.admin.role_permissions.heading=Berechtigungen
+ui.admin.role_permissions.add_permission=Berechtigung hinzuf\u00fcgen
+ui.admin.group_details.add_permission.back=Zur\u00fcck zu den Eigenschaften der Rolle
+ui.admin.role_details.add_permission.heading=Berechtigung zur Rolle {0} hinzuf\u00fcgen
+ui.admin.role_details.add_permission.object_id.label=Objekt ID
+ui.admin.role_details.add_permission.object_id.hint=Die ID des Objektes, auf das die Berechtigung gew\u00e4hrt wird. Wenn keine ID angegeben wird, gilt die Berectigung f\u00fcr alle Objekte.
+ui.admin.role_details.add_permission.privilege.label=Privileg
+ui.admin.role_details.add_permission.privilege.hint=Das gew\u00e4hrte Privileg.
+ui.admin.role_permissions.note=Bitte beachten Sie, dass hier nur eingeschr\u00e4nkte M\u00f6glichkeiten zur Verwaltung der Berechtigungen angeboten werden. Die einzelnen Applikationen bieten in der Regel bessere M\u00f6glichkeiten zur Verwaltung ihrere spezifischen Berechtigungen an.
+ui.admin.role_details.add_permission.privilege.error.notempty=Privileg darf nicht leer sein.
+ui.admin.role_details.add_permission.object_id.error.nan=Keine valide Objekt-ID
+ui.admin.role_details.add_permission.object_id.error.no_object=Es gibt keine Objekt mit der angebenen ID.
diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties
index f1b6db68f..18db4884a 100755
--- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties
+++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties
@@ -297,3 +297,14 @@ ui.admin.role_permissions.on_object=On object
ui.admin.role_permissions.revoke=Revoke
ui.admin.role_permissions.revoke.confirm=Are you sure to revoke this permission?
ui.admin.role_permissions.heading=Permissions
+ui.admin.role_permissions.add_permission=Add permission
+ui.admin.group_details.add_permission.back=Back to role properties
+ui.admin.role_details.add_permission.heading=Add permission to role {0}
+ui.admin.role_details.add_permission.object_id.label=Object id
+ui.admin.role_details.add_permission.object_id.hint=The id for which the new permission is granted. If left empty the permission is granted for all objects.
+ui.admin.role_details.add_permission.privilege.label=Privilege
+ui.admin.role_details.add_permission.privilege.hint=The privilege granted.
+ui.admin.role_permissions.note=Please note that this form only provides very basic facilities for managing permissions. Usually the specific applications provide a better UI for managing their specific permissions.
+ui.admin.role_details.add_permission.privilege.error.notempty=Privilege can't be empty.
+ui.admin.role_details.add_permission.object_id.error.nan=The provided value of object id is not an valid id.
+ui.admin.role_details.add_permission.object_id.error.no_object=There is no object with the provided id.
diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties
index 751e0384a..d90e11e06 100755
--- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties
+++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties
@@ -288,3 +288,14 @@ ui.admin.role_permissions.on_object=On object
ui.admin.role_permissions.revoke=Revoke
ui.admin.role_permissions.revoke.confirm=Are you sure to revoke this permission?
ui.admin.role_permissions.heading=Permissions
+ui.admin.role_permissions.add_permission=Add permission
+ui.admin.group_details.add_permission.back=Back to role properties
+ui.admin.role_details.add_permission.heading=Add permission to role {0}
+ui.admin.role_details.add_permission.object_id.label=Object id
+ui.admin.role_details.add_permission.object_id.hint=The id for which the new permission is granted. If left empty the permission is granted for all objects.
+ui.admin.role_details.add_permission.privilege.label=Privilege
+ui.admin.role_details.add_permission.privilege.hint=The privilege granted.
+ui.admin.role_permissions.note=Please note that this form only provides very basic facilities for managing permissions. Usually the specific applications provide a better UI for managing their specific permissions.
+ui.admin.role_details.add_permission.privilege.error.notempty=Privilege can't be empty.
+ui.admin.role_details.add_permission.object_id.error.nan=The provided value of object id is not an valid id.
+ui.admin.role_details.add_permission.object_id.error.no_object=There is no object with the provided id.