From 87f6c3e6510986a6676872aa64aed66fe7f24b01 Mon Sep 17 00:00:00 2001 From: James Moger Date: Mon, 22 Oct 2012 16:15:40 -0400 Subject: [PATCH] Differentiate between an explicit permission and a regex permission --- src/com/gitblit/GitBlit.java | 30 ++++++++++++------- src/com/gitblit/client/GitblitClient.java | 11 +++++-- .../client/RegistrantPermissionsPanel.java | 30 ++++++++++++++++++- .../RegistrantPermissionsTableModel.java | 18 +++++++++-- .../models/RegistrantAccessPermission.java | 5 +++- src/com/gitblit/models/TeamModel.java | 14 ++++++++- src/com/gitblit/models/UserModel.java | 14 ++++++++- .../gitblit/wicket/GitBlitWebApp.properties | 1 + .../panels/RegistrantPermissionsPanel.html | 4 +-- .../panels/RegistrantPermissionsPanel.java | 26 ++++++++++++---- tests/com/gitblit/tests/RpcTests.java | 4 +-- 11 files changed, 128 insertions(+), 29 deletions(-) diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index ce556b6e..e83da933 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -640,8 +640,10 @@ public class GitBlit implements ServletContextListener { public List getUserAccessPermissions(RepositoryModel repository) { List permissions = new ArrayList(); for (String user : userService.getUsernamesForRepositoryRole(repository.name)) { - AccessPermission ap = userService.getUserModel(user).getRepositoryPermission(repository); - permissions.add(new RegistrantAccessPermission(user, ap, RegistrantType.USER)); + UserModel model = userService.getUserModel(user); + AccessPermission ap = model.getRepositoryPermission(repository); + boolean isExplicit = model.hasExplicitRepositoryPermission(repository.name); + permissions.add(new RegistrantAccessPermission(user, ap, isExplicit, RegistrantType.USER)); } return permissions; } @@ -656,9 +658,12 @@ public class GitBlit implements ServletContextListener { public boolean setUserAccessPermissions(RepositoryModel repository, Collection permissions) { List users = new ArrayList(); for (RegistrantAccessPermission up : permissions) { - UserModel user = userService.getUserModel(up.registrant); - user.setRepositoryPermission(repository.name, up.permission); - users.add(user); + if (up.isExplicit) { + // only set explicitly defined permissions + UserModel user = userService.getUserModel(up.registrant); + user.setRepositoryPermission(repository.name, up.permission); + users.add(user); + } } return userService.updateUserModels(users); } @@ -772,8 +777,10 @@ public class GitBlit implements ServletContextListener { public List getTeamAccessPermissions(RepositoryModel repository) { List permissions = new ArrayList(); for (String team : userService.getTeamnamesForRepositoryRole(repository.name)) { - AccessPermission ap = userService.getTeamModel(team).getRepositoryPermission(repository); - permissions.add(new RegistrantAccessPermission(team, ap, RegistrantType.TEAM)); + TeamModel model = userService.getTeamModel(team); + AccessPermission ap = model.getRepositoryPermission(repository); + boolean isExplicit = model.hasExplicitRepositoryPermission(repository.name); + permissions.add(new RegistrantAccessPermission(team, ap, isExplicit, RegistrantType.TEAM)); } return permissions; } @@ -788,9 +795,12 @@ public class GitBlit implements ServletContextListener { public boolean setTeamAccessPermissions(RepositoryModel repository, Collection permissions) { List teams = new ArrayList(); for (RegistrantAccessPermission tp : permissions) { - TeamModel team = userService.getTeamModel(tp.registrant); - team.setRepositoryPermission(repository.name, tp.permission); - teams.add(team); + if (tp.isExplicit) { + // only set explicitly defined access permissions + TeamModel team = userService.getTeamModel(tp.registrant); + team.setRepositoryPermission(repository.name, tp.permission); + teams.add(team); + } } return userService.updateTeamModels(teams); } diff --git a/src/com/gitblit/client/GitblitClient.java b/src/com/gitblit/client/GitblitClient.java index 9e31c794..4620fefa 100644 --- a/src/com/gitblit/client/GitblitClient.java +++ b/src/com/gitblit/client/GitblitClient.java @@ -28,6 +28,7 @@ import java.util.Set; import java.util.TreeSet; import com.gitblit.Constants; +import com.gitblit.Constants.AccessPermission; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.Constants.AuthorizationControl; import com.gitblit.Constants.RegistrantType; @@ -36,10 +37,10 @@ import com.gitblit.GitBlitException.NotAllowedException; import com.gitblit.GitBlitException.UnauthorizedException; import com.gitblit.GitBlitException.UnknownRequestException; import com.gitblit.Keys; -import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.models.FederationModel; import com.gitblit.models.FeedEntryModel; import com.gitblit.models.FeedModel; +import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.models.RepositoryModel; import com.gitblit.models.ServerSettings; import com.gitblit.models.ServerStatus; @@ -498,7 +499,9 @@ public class GitblitClient implements Serializable { List list = new ArrayList(); for (UserModel user : allUsers) { if (user.hasRepositoryPermission(repository.name)) { - list.add(new RegistrantAccessPermission(user.username, user.permissions.get(repository.name), RegistrantType.USER)); + AccessPermission ap = user.getRepositoryPermission(repository); + boolean isExplicit = user.hasExplicitRepositoryPermission(repository.name); + list.add(new RegistrantAccessPermission(user.username, ap, isExplicit, RegistrantType.USER)); } } return list; @@ -535,7 +538,9 @@ public class GitblitClient implements Serializable { List list = new ArrayList(); for (TeamModel team : allTeams) { if (team.hasRepositoryPermission(repository.name)) { - list.add(new RegistrantAccessPermission(team.name, team.permissions.get(repository.name), RegistrantType.TEAM)); + AccessPermission ap = team.getRepositoryPermission(repository); + boolean isExplicit = team.hasExplicitRepositoryPermission(repository.name); + list.add(new RegistrantAccessPermission(team.name, ap, isExplicit, RegistrantType.TEAM)); } } return list; diff --git a/src/com/gitblit/client/RegistrantPermissionsPanel.java b/src/com/gitblit/client/RegistrantPermissionsPanel.java index fa7ff5a8..4ea173fc 100644 --- a/src/com/gitblit/client/RegistrantPermissionsPanel.java +++ b/src/com/gitblit/client/RegistrantPermissionsPanel.java @@ -29,6 +29,8 @@ import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; +import javax.swing.SwingConstants; +import javax.swing.table.DefaultTableCellRenderer; import com.gitblit.Constants.AccessPermission; import com.gitblit.models.RegistrantAccessPermission; @@ -59,8 +61,10 @@ public class RegistrantPermissionsPanel extends JPanel { JScrollPane jsp = new JScrollPane(permissionsTable); add(jsp, BorderLayout.CENTER); + permissionsTable.getColumnModel().getColumn(RegistrantPermissionsTableModel.Columns.Type.ordinal()) + .setCellRenderer(new RegexRenderer()); permissionsTable.getColumnModel().getColumn(RegistrantPermissionsTableModel.Columns.Permission.ordinal()) - .setCellEditor(new AccessPermissionEditor()); + .setCellEditor(new AccessPermissionEditor()); registrantModel = new DefaultComboBoxModel(); registrantSelector = new JComboBox(registrantModel); @@ -137,4 +141,28 @@ public class RegistrantPermissionsPanel extends JPanel { super(new JComboBox(AccessPermission.values())); } } + + private class RegexRenderer extends DefaultTableCellRenderer { + + private static final long serialVersionUID = 1L; + + public RegexRenderer() { + super(); + setHorizontalAlignment(SwingConstants.CENTER); + } + + @Override + protected void setValue(Object value) { + boolean isExplicit = (Boolean) value; + if (isExplicit) { + // explicit permission + setText(""); + setToolTipText(null); + } else { + // regex matched permission + setText("regex"); + setToolTipText(Translation.get("gb.regexPermission")); + } + } + } } diff --git a/src/com/gitblit/client/RegistrantPermissionsTableModel.java b/src/com/gitblit/client/RegistrantPermissionsTableModel.java index 91acec8b..fcd9c8b4 100644 --- a/src/com/gitblit/client/RegistrantPermissionsTableModel.java +++ b/src/com/gitblit/client/RegistrantPermissionsTableModel.java @@ -36,7 +36,7 @@ public class RegistrantPermissionsTableModel extends AbstractTableModel { List permissions; enum Columns { - Registrant, Permission; + Registrant, Type, Permission; @Override public String toString() { @@ -72,6 +72,8 @@ public class RegistrantPermissionsTableModel extends AbstractTableModel { switch (col) { case Registrant: return Translation.get("gb.name"); + case Type: + return Translation.get("gb.type"); case Permission: return Translation.get("gb.permission"); } @@ -88,13 +90,23 @@ public class RegistrantPermissionsTableModel extends AbstractTableModel { public Class getColumnClass(int columnIndex) { if (columnIndex == Columns.Permission.ordinal()) { return AccessPermission.class; + } else if (columnIndex == Columns.Type.ordinal()) { + return Boolean.class; } return String.class; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == Columns.Permission.ordinal(); + if (columnIndex == Columns.Permission.ordinal()) { + // in order for the permission to be editable it must be + // explicitly defined on the object. regex permissions are inherited + // and therefore can not be directly manipulated unless the current + // object is the source of the regex (i.e. a user or team with explicit + // regex definition) + return permissions.get(rowIndex).isExplicit; + } + return false; } @Override @@ -104,6 +116,8 @@ public class RegistrantPermissionsTableModel extends AbstractTableModel { switch (col) { case Registrant: return rp.registrant; + case Type: + return rp.isExplicit; case Permission: return rp.permission; } diff --git a/src/com/gitblit/models/RegistrantAccessPermission.java b/src/com/gitblit/models/RegistrantAccessPermission.java index 93027450..4a560d43 100644 --- a/src/com/gitblit/models/RegistrantAccessPermission.java +++ b/src/com/gitblit/models/RegistrantAccessPermission.java @@ -33,13 +33,16 @@ public class RegistrantAccessPermission implements Serializable, Comparable { public List getRepositoryPermissions() { List list = new ArrayList(); for (Map.Entry entry : permissions.entrySet()) { - list.add(new RegistrantAccessPermission(entry.getKey(), entry.getValue(), RegistrantType.REPOSITORY)); + list.add(new RegistrantAccessPermission(entry.getKey(), entry.getValue(), true, RegistrantType.REPOSITORY)); } Collections.sort(list); return list; @@ -129,6 +129,18 @@ public class TeamModel implements Serializable, Comparable { return false; } + /** + * Returns true if the team has an explicitly specified access permission for + * this repository. + * + * @param name + * @return if the team has an explicitly specified access permission + */ + public boolean hasExplicitRepositoryPermission(String name) { + String repository = AccessPermission.repositoryFromRole(name).toLowerCase(); + return permissions.containsKey(repository); + } + /** * Adds a repository permission to the team. *

diff --git a/src/com/gitblit/models/UserModel.java b/src/com/gitblit/models/UserModel.java index 77337043..97430bfe 100644 --- a/src/com/gitblit/models/UserModel.java +++ b/src/com/gitblit/models/UserModel.java @@ -137,7 +137,7 @@ public class UserModel implements Principal, Serializable, Comparable public List getRepositoryPermissions() { List list = new ArrayList(); for (Map.Entry entry : permissions.entrySet()) { - list.add(new RegistrantAccessPermission(entry.getKey(), entry.getValue(), RegistrantType.REPOSITORY)); + list.add(new RegistrantAccessPermission(entry.getKey(), entry.getValue(), true, RegistrantType.REPOSITORY)); } Collections.sort(list); return list; @@ -169,6 +169,18 @@ public class UserModel implements Principal, Serializable, Comparable return false; } + /** + * Returns true if the user has an explicitly specified access permission for + * this repository. + * + * @param name + * @return if the user has an explicitly specified access permission + */ + public boolean hasExplicitRepositoryPermission(String name) { + String repository = AccessPermission.repositoryFromRole(name).toLowerCase(); + return permissions.containsKey(repository); + } + /** * Adds a repository permission to the team. *

diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index bdeb4a95..41cbdd46 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -356,3 +356,4 @@ gb.createPermission = {0} (push, ref creation) gb.deletePermission = {0} (push, ref creation+deletion) gb.rewindPermission = {0} (push, ref creation+deletion+rewind) gb.permission = permission +gb.regexPermission = this permission is set from a regular expression \ No newline at end of file diff --git a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html index dd76d9fd..f5da1c6f 100644 --- a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html +++ b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html @@ -8,8 +8,8 @@

-
- +
+
[regex]
diff --git a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java index 936659d2..9dee2f26 100644 --- a/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java +++ b/src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java @@ -38,6 +38,7 @@ import org.apache.wicket.model.IModel; import com.gitblit.Constants.AccessPermission; import com.gitblit.models.RegistrantAccessPermission; import com.gitblit.utils.DeepCopier; +import com.gitblit.wicket.WicketUtils; /** * Allows user to manipulate registrant access permissions. @@ -78,20 +79,33 @@ public class RegistrantPermissionsPanel extends BasePanel { public void populateItem(final Item item) { final RegistrantAccessPermission entry = item.getModelObject(); item.add(new Label("registrant", entry.registrant)); + if (entry.isExplicit) { + item.add(new Label("regex", "").setVisible(false)); + } else { + Label regex = new Label("regex", "regex"); + WicketUtils.setHtmlTooltip(regex, getString("gb.regexPermission")); + item.add(regex); + } // use ajax to get immediate update of permission level change // otherwise we can lose it if they change levels and then add // a new repository permission final DropDownChoice permissionChoice = new DropDownChoice( "permission", Arrays.asList(AccessPermission.values()), new AccessPermissionRenderer(translations)); - permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { + // only allow changing an explicitly defined permission + // this is designed to prevent changing a regex permission in + // a repository + permissionChoice.setEnabled(entry.isExplicit); + if (entry.isExplicit) { + permissionChoice.add(new AjaxFormComponentUpdatingBehavior("onchange") { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - protected void onUpdate(AjaxRequestTarget target) { - target.addComponent(permissionChoice); - } - }); + protected void onUpdate(AjaxRequestTarget target) { + target.addComponent(permissionChoice); + } + }); + } item.add(permissionChoice); } diff --git a/tests/com/gitblit/tests/RpcTests.java b/tests/com/gitblit/tests/RpcTests.java index c739eba3..0be2e02a 100644 --- a/tests/com/gitblit/tests/RpcTests.java +++ b/tests/com/gitblit/tests/RpcTests.java @@ -199,7 +199,7 @@ public class RpcTests { List permissions = RpcUtils.getRepositoryMemberPermissions(retrievedRepository, url, account, password.toCharArray()); assertEquals("Membership permissions is not empty!", 0, permissions.size()); - permissions.add(new RegistrantAccessPermission(testMember.username, AccessPermission.PUSH, RegistrantType.USER)); + permissions.add(new RegistrantAccessPermission(testMember.username, AccessPermission.PUSH, true, RegistrantType.USER)); assertTrue( "Failed to set member permissions!", RpcUtils.setRepositoryMemberPermissions(retrievedRepository, permissions, url, account, @@ -288,7 +288,7 @@ public class RpcTests { // set no teams List permissions = new ArrayList(); for (String team : helloworldTeams) { - permissions.add(new RegistrantAccessPermission(team, AccessPermission.NONE, RegistrantType.TEAM)); + permissions.add(new RegistrantAccessPermission(team, AccessPermission.NONE, true, RegistrantType.TEAM)); } assertTrue(RpcUtils.setRepositoryTeamPermissions(helloworld, permissions, url, account, password.toCharArray())); -- 2.39.5