Author: ate Date: Tue Sep 27 03:17:29 2011 New Revision: 1176185 URL: http://svn.apache.org/viewvc?rev=1176185&view=rev Log: JS2-1100: delegated security enforcement for non-admin users while maintaining principals See: https://issues.apache.org/jira/browse/JS2-1100?focusedCommentId=13115168 And, this automatically also implements JS2-915
Added: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalStatusPanel.html (contents, props changed) - copied, changed from r1102191, portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalProfilePanel.html Removed: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalProfilePanel.html Modified: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet.java portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$UserPrincipalProfilePanel.html Modified: portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet.java?rev=1176185&r1=1176184&r2=1176185&view=diff ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet.java (original) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/java/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet.java Tue Sep 27 03:17:29 2011 @@ -28,9 +28,9 @@ import java.util.List; import java.util.Map; import javax.portlet.PortletPreferences; +import javax.security.auth.Subject; import org.apache.commons.lang.StringUtils; -import org.apache.jetspeed.administration.PortalConfiguration; import org.apache.jetspeed.administration.PortalConfigurationConstants; import org.apache.jetspeed.audit.AuditActivity; import org.apache.jetspeed.om.folder.Folder; @@ -57,9 +57,11 @@ import org.apache.jetspeed.security.Pass import org.apache.jetspeed.security.RoleManager; import org.apache.jetspeed.security.SecurityAttribute; import org.apache.jetspeed.security.SecurityException; +import org.apache.jetspeed.security.SubjectHelper; import org.apache.jetspeed.security.User; import org.apache.jetspeed.security.UserCredential; import org.apache.jetspeed.security.UserManager; +import org.apache.jetspeed.security.UserSubjectPrincipal; import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator; import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByLink; import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByLink.VoidCssProvider; @@ -886,36 +888,28 @@ public class JetspeedPrincipalManagement } } - protected class PrincipalProfilePanel extends Panel + protected class PrincipalStatusPanel extends Panel { - protected boolean userEnabled = false; + protected boolean principalEnabled = false; protected String name; - protected String locatorName; - - protected String ruleName; - - protected List fullRules; - - protected List userRules; - /** - * @param userEnabled - * the userEnabled to set + * @param principalEnabled + * the principalEnabled to set */ - public void setUserEnabled(boolean userEnabled) + public void setPrincipalEnabled(boolean principalEnabled) { - this.userEnabled = userEnabled; + this.principalEnabled = principalEnabled; } /** - * @return the userEnabled + * @return the principalEnabled */ - public boolean isUserEnabled() + public boolean isPrincipalEnabled() { - return userEnabled; + return principalEnabled; } /** @@ -924,18 +918,18 @@ public class JetspeedPrincipalManagement protected String getName() { return name; - } + } - protected PrincipalProfilePanel(String id) + protected PrincipalStatusPanel(String id) { super(id); - Form profileForm = new Form("profileForm"); - add(profileForm); - profileForm.add(new CheckBox("userStatus", new PropertyModel(this, - "userEnabled"))); - profileForm.add(new Label("enabledLabel", new ResourceModel( + Form statusForm = new Form("statusForm"); + add(statusForm); + statusForm.add(new CheckBox("principalStatus", new PropertyModel(this, + "principalEnabled"))); + statusForm.add(new Label("enabledLabel", new ResourceModel( "common.enabled"))); - profileForm.add(new Button("submit", new ResourceModel( + statusForm.add(new Button("submit", new ResourceModel( principalParam + ".update.button")){ @Override public void onSubmit() @@ -944,7 +938,7 @@ public class JetspeedPrincipalManagement getName()); try { - principal.setEnabled(isUserEnabled()); + principal.setEnabled(isPrincipalEnabled()); getManager().updatePrincipal(principal); setPrincipal(principal); principalDataProvider.refresh(getManager(),getSearchString()); @@ -954,7 +948,7 @@ public class JetspeedPrincipalManagement } } }); - profileForm.add(new Button("remove", new ResourceModel(principalParam + ".remove.button")){ + statusForm.add(new Button("remove", new ResourceModel(principalParam + ".remove.button")){ @Override public void onSubmit() { @@ -972,6 +966,7 @@ public class JetspeedPrincipalManagement } }.add(new JavascriptEventConfirmation("onclick", new ResourceModel("action.delete.confirm")))); + add(new FeedbackPanel("feedback")); } @Override @@ -979,7 +974,7 @@ public class JetspeedPrincipalManagement { if (getPrincipal() != null) { - this.userEnabled = getPrincipal().isEnabled(); + this.principalEnabled = getPrincipal().isEnabled(); this.name = getPrincipal().getName(); } super.onBeforeRender(); @@ -1539,7 +1534,10 @@ public class JetspeedPrincipalManagement protected JetspeedPrincipalAssociationType associationType; protected boolean associationsFrom; - + + protected boolean admin; + protected boolean modificationAllowed = true; + /** * @return the associations */ @@ -1602,6 +1600,17 @@ public class JetspeedPrincipalManagement this.associationType = AssociationType; associationName = AssociationType.getAssociationName(); final String assoctionName = AssociationType.getAssociationName(); + String adminRole = getServiceLocator().getPortalConfiguration().getString(PortalConfigurationConstants.ROLES_DEFAULT_ADMIN); + admin = getPortletRequest().isUserInRole(adminRole); + if (!admin && !principal.getType().getName().equals(JetspeedPrincipalType.USER)) + { + // no non-user type principal modification is allowed if the current user itself doesn't have this principal + UserSubjectPrincipal currentUser = (UserSubjectPrincipal)getPortletRequest().getUserPrincipal(); + if (!hasPrincipal(currentUser.getSubject(), principal)) + { + modificationAllowed = false; + } + } refreshList(); ListView commentListView = new ListView("comments", new PropertyModel(this, "associations")) @@ -1612,6 +1621,7 @@ public class JetspeedPrincipalManagement final JetspeedPrincipal principal = (JetspeedPrincipal) listItem .getModelObject(); listItem.add(new Label("Name", principal.getName())); + boolean deleteAllowed = modificationAllowed; Link deleteLink = new Link("delete") { @@ -1639,13 +1649,29 @@ public class JetspeedPrincipalManagement }; deleteLink.add(new Label("deleteLabel", new ResourceModel( "common.delete"))); + if (!admin && deleteAllowed && !principal.getType().getName().equals(JetspeedPrincipalType.USER)) + { + // restrict deleting non-user type principals to only those the current user itself has + UserSubjectPrincipal currentUser = (UserSubjectPrincipal)getPortletRequest().getUserPrincipal(); + if (!hasPrincipal(currentUser.getSubject(), principal)) + { + deleteAllowed = false; + } + } + if (!deleteAllowed || !modificationAllowed) + { + deleteLink.setEnabled(false); + deleteLink.setVisible(false); + } listItem.add(deleteLink); } }; if(AssociationType.getFromPrincipalType().equals(principalType)) { add(new Label("principalReleation",new ResourceModel(AssociationType.getToPrincipalType().getName()))); - }else{ + } + else + { add(new Label("principalReleation",new ResourceModel(AssociationType.getFromPrincipalType().getName()))); } add(commentListView); @@ -1658,8 +1684,7 @@ public class JetspeedPrincipalManagement new ChoiceRenderer("name", "name")); dropDown.setRequired(true); assocationsForm.add(dropDown); - Button addRelations = new Button("addRelations", new ResourceModel( - "common.association.add")) + Button addRelations = new Button("addRelations", new ResourceModel("common.association.add")) { @Override @@ -1680,6 +1705,7 @@ public class JetspeedPrincipalManagement getManager().addAssociation(toPrincipal, fromPrincipal, associationName); } + associationPrincipal = null; refreshList(); } catch (SecurityException sExc) @@ -1700,85 +1726,107 @@ public class JetspeedPrincipalManagement private void refreshList() { - List filter = null; names.clear(); - String adminRole = getServiceLocator().getPortalConfiguration().getString(PortalConfigurationConstants.ROLES_DEFAULT_ADMIN); - if (associationType.getFromPrincipalType().getName().equals(JetspeedPrincipalType.USER) && - (associationType.getToPrincipalType().getName().equals(JetspeedPrincipalType.ROLE) || - associationType.getToPrincipalType().getName().equals(JetspeedPrincipalType.GROUP))) - { - if (!getPortletRequest().isUserInRole(adminRole)) - { - Principal currentUser = getPortletRequest().getUserPrincipal(); - filter = getBaseManager( - associationType.getToPrincipalType()) - .getAssociatedFrom(currentUser.getName(), - principal.getType(), - associationType.getAssociationName()); - } - } if (!principal.getType().equals( associationType.getFromPrincipalType())) { - associations = getBaseManager( + associations = getBaseManager( associationType.getFromPrincipalType()) .getAssociatedTo(principal.getName(), principal.getType(), associationType.getAssociationName()); - List tempNames = getBaseManager( - associationType.getFromPrincipalType()).getPrincipals( - ""); - for (int index = 0; index < tempNames.size(); index++) - { - names.add(tempNames.get(index)); - } + if (modificationAllowed) + { + List tempNames = getBaseManager( + associationType.getFromPrincipalType()).getPrincipals( + ""); + for (int index = 0; index < tempNames.size(); index++) + { + + JetspeedPrincipal tmpPrincipal = (JetspeedPrincipal)tempNames.get(index); + if (!(tmpPrincipal.getType().getName().equals(principal.getType().getName()) && + tmpPrincipal.getName().equals(principal.getName()))) + { + names.add(tmpPrincipal); + } + } + } associationsFrom = false; - } else + } + else { associations = getBaseManager( associationType.getToPrincipalType()) .getAssociatedFrom(principal.getName(), principal.getType(), associationType.getAssociationName()); - List tempNames = getBaseManager( - associationType.getToPrincipalType()).getPrincipals(""); - for (int index = 0; index < tempNames.size(); index++) - { - names.add(tempNames.get(index)); + if (modificationAllowed) + { + List tempNames = getBaseManager( + associationType.getToPrincipalType()).getPrincipals(""); + for (int index = 0; index < tempNames.size(); index++) + { + JetspeedPrincipal tmpPrincipal = (JetspeedPrincipal)tempNames.get(index); + if (!(tmpPrincipal.getType().getName().equals(principal.getType().getName()) && + tmpPrincipal.getName().equals(principal.getName()))) + { + names.add(tmpPrincipal); + } + } } associationsFrom = true; } - for (int count = 0; count < associations.size(); count++) - { - JetspeedPrincipal tmpPrincipal = (JetspeedPrincipal) associations - .get(count); - JetspeedPrincipal listPrincipal; - for (int index = 0; index < names.size(); index++) + if (modificationAllowed) + { + for (int count = 0; count < associations.size(); count++) { - listPrincipal = (JetspeedPrincipal) names.get(index); - if (listPrincipal.getName().equals(tmpPrincipal.getName())) + JetspeedPrincipal tmpPrincipal = (JetspeedPrincipal) associations.get(count); + JetspeedPrincipal listPrincipal; + for (int index = names.size()-1; index > -1; index--) { - names.remove(index); + listPrincipal = (JetspeedPrincipal) names.get(index); + if (listPrincipal.getName().equals(tmpPrincipal.getName())) + { + names.remove(index); + } } } - } - if (filter != null) + } + if (names.size() > 0 && !admin) { - List copy = new ArrayList(); - for (int index = 0; index < names.size(); index++) + // restrict creating new associations to only those the user itself belongs to + String jptName = associationsFrom ? associationType.getToPrincipalType().getName() : associationType.getFromPrincipalType().getName(); + if (!jptName.equals(JetspeedPrincipalType.USER)) { - JetspeedPrincipal listPrincipal = (JetspeedPrincipal) names.get(index); - for (int count = 0; count < filter.size(); count++) - { - JetspeedPrincipal tmpPrincipal = (JetspeedPrincipal) filter.get(count); - if (listPrincipal.getName().equals(tmpPrincipal.getName())) - { - copy.add(listPrincipal); - break; - } - } + // get all current user principals of asssignable type as restricted list + UserSubjectPrincipal currentUser = (UserSubjectPrincipal)getPortletRequest().getUserPrincipal(); + List<JetspeedPrincipal> filter = SubjectHelper.getPrincipals(currentUser.getSubject(), jptName); + if (filter.isEmpty()) + { + names.clear(); + } + else + { + for (int index = names.size()-1; index > -1; index--) + { + boolean found = false; + JetspeedPrincipal listPrincipal = (JetspeedPrincipal) names.get(index); + for (int count = 0; count < filter.size(); count++) + { + JetspeedPrincipal tmpPrincipal = filter.get(count); + if (listPrincipal.getName().equals(tmpPrincipal.getName())) + { + found = true; + break; + } + } + if (!found) + { + names.remove(index); + } + } + } } - names = copy; } } } @@ -1952,26 +2000,44 @@ public class JetspeedPrincipalManagement { if (principalType.getName().equals(JetspeedPrincipalType.USER)) { - tab = new AbstractTab(new Model("User Profile")) + String adminRole = getServiceLocator().getPortalConfiguration().getString(PortalConfigurationConstants.ROLES_DEFAULT_ADMIN); + boolean disableAdminEdit = true; + try { - - public Panel getPanel(String panelId) + if (!((RoleManager)getRoleManager()).isUserInRole(principal.getName(), adminRole) || getPortletRequest().isUserInRole(adminRole)) { - return new UserPrincipalProfilePanel(panelId); + disableAdminEdit = false; } - }; - } else + } + catch (SecurityException e) + { + // ignore + } + if (disableAdminEdit) + { + return; + } + } + tab = new AbstractTab(new Model("Status")) + { + public Panel getPanel(String panelId) + { + return new PrincipalStatusPanel(panelId); + } + }; + panel.getTabs().add(tab); + if (principalType.getName().equals(JetspeedPrincipalType.USER)) { tab = new AbstractTab(new Model("User Profile")) { public Panel getPanel(String panelId) { - return new PrincipalProfilePanel(panelId); + return new UserPrincipalProfilePanel(panelId); } }; - } - panel.getTabs().add(tab); + panel.getTabs().add(tab); + } tab = new AbstractTab(new Model("Associations")) { @@ -2061,4 +2127,20 @@ public class JetspeedPrincipalManagement { return (JetspeedPrincipalManager) getServiceLocator().getRoleManager(); } + + private static boolean hasPrincipal(Subject subject, JetspeedPrincipal jp) + { + Iterator<Principal> principals = subject.getPrincipals().iterator(); + while (principals.hasNext()) + { + Principal p = principals.next(); + if (p instanceof JetspeedPrincipal && + ((JetspeedPrincipal)p).getType().getName().equals(jp.getType().getName()) && p.getName().equals(jp.getName())) + { + return true; + } + } + return false; + } + } Copied: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalStatusPanel.html (from r1102191, portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalProfilePanel.html) URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet%24PrincipalStatusPanel.html?p2=portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet%24PrincipalStatusPanel.html&p1=portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet%24PrincipalProfilePanel.html&r1=1102191&r2=1176185&rev=1176185&view=diff ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalProfilePanel.html (original) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalStatusPanel.html Tue Sep 27 03:17:29 2011 @@ -20,8 +20,10 @@ <html xmlns="http://www.w3.org/1999/xhtml" > <wicket:panel> - <form wicket:id="profileForm"> - <input type="checkbox" wicket:id="userStatus" /><span wicket:id="enabledLabel"/> + +<div wicket:id="feedback"></div> + <form wicket:id="statusForm"> + <input type="checkbox" wicket:id="principalStatus" /><span wicket:id="enabledLabel"/> <input type="submit" wicket:id="submit" /> <input type="submit" wicket:id="remove" /> </form> Propchange: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalStatusPanel.html ------------------------------------------------------------------------------ svn:eol-style = native Propchange: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalStatusPanel.html ------------------------------------------------------------------------------ svn:keywords = Id Propchange: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$PrincipalStatusPanel.html ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$UserPrincipalProfilePanel.html URL: http://svn.apache.org/viewvc/portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet%24UserPrincipalProfilePanel.html?rev=1176185&r1=1176184&r2=1176185&view=diff ============================================================================== --- portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$UserPrincipalProfilePanel.html (original) +++ portals/jetspeed-2/applications/j2-admin/trunk/src/main/resources/org/apache/jetspeed/portlets/security/JetspeedPrincipalManagementPortlet$UserPrincipalProfilePanel.html Tue Sep 27 03:17:29 2011 @@ -20,22 +20,8 @@ <html xmlns="http://www.w3.org/1999/xhtml"> <wicket:panel> - <div wicket:id="feedback"></div> - <br/><br/> - <form wicket:id="profileForm"> - <table> - <tr> - <td><input type="checkbox" wicket:id="userEnabled" - class="portlet-form-button" /></td> - <td><span wicket:id="enabledLabel"></span></td> - <td><input type="submit" wicket:id="submit" - class="portlet-form-button" /></td> - <td><input type="submit" wicket:id="remove" - class="portlet-form-button" /></td> - </tr> - </table> - </form> - <hr /> + +<div wicket:id="feedback"></div> <form wicket:id="userRulesForm"> <table wicket:id="entries" cellpadding="0" cellspacing="1" border="0"> </table> --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscr...@portals.apache.org For additional commands, e-mail: jetspeed-dev-h...@portals.apache.org