James Moger
2012-10-22 87f6c3e6510986a6676872aa64aed66fe7f24b01
Differentiate between an explicit permission and a regex permission
11 files modified
131 ■■■■ changed files
src/com/gitblit/GitBlit.java 18 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitClient.java 11 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/RegistrantPermissionsPanel.java 28 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/RegistrantPermissionsTableModel.java 18 ●●●● patch | view | raw | blame | history
src/com/gitblit/models/RegistrantAccessPermission.java 5 ●●●● patch | view | raw | blame | history
src/com/gitblit/models/TeamModel.java 14 ●●●●● patch | view | raw | blame | history
src/com/gitblit/models/UserModel.java 14 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp.properties 1 ●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html 4 ●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java 14 ●●●●● patch | view | raw | blame | history
tests/com/gitblit/tests/RpcTests.java 4 ●●●● patch | view | raw | blame | history
src/com/gitblit/GitBlit.java
@@ -640,8 +640,10 @@
    public List<RegistrantAccessPermission> getUserAccessPermissions(RepositoryModel repository) {
        List<RegistrantAccessPermission> permissions = new ArrayList<RegistrantAccessPermission>();
        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 boolean setUserAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
        List<UserModel> users = new ArrayList<UserModel>();
        for (RegistrantAccessPermission up : permissions) {
            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 List<RegistrantAccessPermission> getTeamAccessPermissions(RepositoryModel repository) {
        List<RegistrantAccessPermission> permissions = new ArrayList<RegistrantAccessPermission>();
        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,10 +795,13 @@
    public boolean setTeamAccessPermissions(RepositoryModel repository, Collection<RegistrantAccessPermission> permissions) {
        List<TeamModel> teams = new ArrayList<TeamModel>();
        for (RegistrantAccessPermission tp : permissions) {
            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);
    }
    
src/com/gitblit/client/GitblitClient.java
@@ -28,6 +28,7 @@
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.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 @@
        List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
        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 @@
        List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
        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;
src/com/gitblit/client/RegistrantPermissionsPanel.java
@@ -29,6 +29,8 @@
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,6 +61,8 @@
        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());
        
@@ -137,4 +141,28 @@
            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"));
            }
        }
    }
}
src/com/gitblit/client/RegistrantPermissionsTableModel.java
@@ -36,7 +36,7 @@
    List<RegistrantAccessPermission> permissions;
    enum Columns {
        Registrant, Permission;
        Registrant, Type, Permission;
        @Override
        public String toString() {
@@ -72,6 +72,8 @@
        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<?> 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 @@
        switch (col) {
        case Registrant:
            return rp.registrant;
        case Type:
            return rp.isExplicit;
        case Permission:
            return rp.permission;
        }
src/com/gitblit/models/RegistrantAccessPermission.java
@@ -33,13 +33,16 @@
    public String registrant;
    public AccessPermission permission;
    public RegistrantType type;
    public boolean isExplicit;
    public RegistrantAccessPermission() {
        isExplicit = true;
    }
    
    public RegistrantAccessPermission(String registrant, AccessPermission permission, RegistrantType type) {
    public RegistrantAccessPermission(String registrant, AccessPermission permission, boolean isExplicit, RegistrantType type) {
        this.registrant = registrant;
        this.permission = permission;
        this.isExplicit = isExplicit;
        this.type = type;
    }
    
src/com/gitblit/models/TeamModel.java
@@ -97,7 +97,7 @@
    public List<RegistrantAccessPermission> getRepositoryPermissions() {
        List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
        for (Map.Entry<String, AccessPermission> 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;
@@ -130,6 +130,18 @@
    }
    
    /**
     * 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.
     * <p>
     * Role may be formatted as:
src/com/gitblit/models/UserModel.java
@@ -137,7 +137,7 @@
    public List<RegistrantAccessPermission> getRepositoryPermissions() {
        List<RegistrantAccessPermission> list = new ArrayList<RegistrantAccessPermission>();
        for (Map.Entry<String, AccessPermission> 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;
@@ -170,6 +170,18 @@
    }
    
    /**
     * 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.
     * <p>
     * Role may be formatted as:
src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -356,3 +356,4 @@
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
src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.html
@@ -8,8 +8,8 @@
<wicket:panel>
    <div wicket:id="permissionRow">
        <div style="padding-top:10px" class="row-fluid">
            <span class="span8" wicket:id="registrant"></span> <select class="input-medium" wicket:id="permission"></select>
        <div style="padding-top:10px;border-left:1px solid #ccc;border-right:1px solid #ccc;" class="row-fluid">
            <div style="padding-top:5px;padding-left:5px;" class="span6" wicket:id="registrant"></div><div style="padding-top:5px;" class="span2"><span class="label label-info" wicket:id="regex">[regex]</span></div> <select class="input-medium" wicket:id="permission"></select>
        </div>
    </div>
src/com/gitblit/wicket/panels/RegistrantPermissionsPanel.java
@@ -38,6 +38,7 @@
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,12 +79,24 @@
            public void populateItem(final Item<RegistrantAccessPermission> 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<AccessPermission> permissionChoice = new DropDownChoice<AccessPermission>(
                        "permission", Arrays.asList(AccessPermission.values()), new AccessPermissionRenderer(translations));
                // 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;
@@ -92,6 +105,7 @@
                        target.addComponent(permissionChoice);
                    }
                });
                }
                item.add(permissionChoice);
            }
tests/com/gitblit/tests/RpcTests.java
@@ -199,7 +199,7 @@
        List<RegistrantAccessPermission> 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 @@
        // set no teams
        List<RegistrantAccessPermission> permissions = new ArrayList<RegistrantAccessPermission>();
        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()));