]> source.dussan.org Git - gitblit.git/commitdiff
Allow authentication providers to control user and team role changes 91/191/1
authorJames Moger <james.moger@gitblit.com>
Thu, 25 Sep 2014 16:15:27 +0000 (12:15 -0400)
committerJames Moger <james.moger@gitblit.com>
Fri, 26 Sep 2014 13:11:20 +0000 (09:11 -0400)
15 files changed:
src/main/java/com/gitblit/ConfigUserService.java
src/main/java/com/gitblit/Constants.java
src/main/java/com/gitblit/auth/AuthenticationProvider.java
src/main/java/com/gitblit/auth/HtpasswdAuthProvider.java
src/main/java/com/gitblit/auth/LdapAuthProvider.java
src/main/java/com/gitblit/auth/PAMAuthProvider.java
src/main/java/com/gitblit/auth/RedmineAuthProvider.java
src/main/java/com/gitblit/auth/SalesforceAuthProvider.java
src/main/java/com/gitblit/auth/WindowsAuthProvider.java
src/main/java/com/gitblit/manager/AuthenticationManager.java
src/main/java/com/gitblit/manager/GitblitManager.java
src/main/java/com/gitblit/manager/IAuthenticationManager.java
src/main/java/com/gitblit/servlet/AuthenticationFilter.java
src/main/java/com/gitblit/wicket/pages/EditTeamPage.java
src/main/java/com/gitblit/wicket/pages/EditUserPage.java

index d7d6c14f1664f048f0a3a26fb5a4406ffbc95487..200ec8a6560927f76e53327f538b7fcf052f6fc3 100644 (file)
@@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory;
 \r
 import com.gitblit.Constants.AccessPermission;\r
 import com.gitblit.Constants.AccountType;\r
+import com.gitblit.Constants.Role;\r
 import com.gitblit.Constants.Transport;\r
 import com.gitblit.manager.IRuntimeManager;\r
 import com.gitblit.models.TeamModel;\r
@@ -734,22 +735,22 @@ public class ConfigUserService implements IUserService {
                        // user roles\r
                        List<String> roles = new ArrayList<String>();\r
                        if (model.canAdmin) {\r
-                               roles.add(Constants.ADMIN_ROLE);\r
+                               roles.add(Role.ADMIN.getRole());\r
                        }\r
                        if (model.canFork) {\r
-                               roles.add(Constants.FORK_ROLE);\r
+                               roles.add(Role.FORK.getRole());\r
                        }\r
                        if (model.canCreate) {\r
-                               roles.add(Constants.CREATE_ROLE);\r
+                               roles.add(Role.CREATE.getRole());\r
                        }\r
                        if (model.excludeFromFederation) {\r
-                               roles.add(Constants.NOT_FEDERATED_ROLE);\r
+                               roles.add(Role.NOT_FEDERATED.getRole());\r
                        }\r
                        if (roles.size() == 0) {\r
                                // we do this to ensure that user record with no password\r
                                // is written.  otherwise, StoredConfig optimizes that account\r
                                // away. :(\r
-                               roles.add(Constants.NO_ROLE);\r
+                               roles.add(Role.NONE.getRole());\r
                        }\r
                        config.setStringList(USER, model.username, ROLE, roles);\r
 \r
@@ -778,18 +779,18 @@ public class ConfigUserService implements IUserService {
                        // team roles\r
                        List<String> roles = new ArrayList<String>();\r
                        if (model.canAdmin) {\r
-                               roles.add(Constants.ADMIN_ROLE);\r
+                               roles.add(Role.ADMIN.getRole());\r
                        }\r
                        if (model.canFork) {\r
-                               roles.add(Constants.FORK_ROLE);\r
+                               roles.add(Role.FORK.getRole());\r
                        }\r
                        if (model.canCreate) {\r
-                               roles.add(Constants.CREATE_ROLE);\r
+                               roles.add(Role.CREATE.getRole());\r
                        }\r
                        if (roles.size() == 0) {\r
                                // we do this to ensure that team record is written.\r
                                // Otherwise, StoredConfig might optimizes that record away.\r
-                               roles.add(Constants.NO_ROLE);\r
+                               roles.add(Role.NONE.getRole());\r
                        }\r
                        config.setStringList(TEAM, model.name, ROLE, roles);\r
                        if (model.accountType != null) {\r
@@ -911,10 +912,10 @@ public class ConfigUserService implements IUserService {
                                        // user roles\r
                                        Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(\r
                                                        USER, username, ROLE)));\r
-                                       user.canAdmin = roles.contains(Constants.ADMIN_ROLE);\r
-                                       user.canFork = roles.contains(Constants.FORK_ROLE);\r
-                                       user.canCreate = roles.contains(Constants.CREATE_ROLE);\r
-                                       user.excludeFromFederation = roles.contains(Constants.NOT_FEDERATED_ROLE);\r
+                                       user.canAdmin = roles.contains(Role.ADMIN.getRole());\r
+                                       user.canFork = roles.contains(Role.FORK.getRole());\r
+                                       user.canCreate = roles.contains(Role.CREATE.getRole());\r
+                                       user.excludeFromFederation = roles.contains(Role.NOT_FEDERATED.getRole());\r
 \r
                                        // repository memberships\r
                                        if (!user.canAdmin) {\r
@@ -947,9 +948,9 @@ public class ConfigUserService implements IUserService {
                                        TeamModel team = new TeamModel(teamname);\r
                                        Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(\r
                                                        TEAM, teamname, ROLE)));\r
-                                       team.canAdmin = roles.contains(Constants.ADMIN_ROLE);\r
-                                       team.canFork = roles.contains(Constants.FORK_ROLE);\r
-                                       team.canCreate = roles.contains(Constants.CREATE_ROLE);\r
+                                       team.canAdmin = roles.contains(Role.ADMIN.getRole());\r
+                                       team.canFork = roles.contains(Role.FORK.getRole());\r
+                                       team.canCreate = roles.contains(Role.CREATE.getRole());\r
                                        team.accountType = AccountType.fromString(config.getString(TEAM, teamname, ACCOUNTTYPE));\r
 \r
                                        if (!team.canAdmin) {\r
index 279d3c9217edf51cf383ce991b802571f663169f..aaa6e69c6f51d7eaa75ecc301cfebf71075d87bd 100644 (file)
@@ -36,14 +36,19 @@ public class Constants {
 \r
        public static final String FULL_NAME = "Gitblit - a pure Java Git solution";\r
 \r
+       @Deprecated\r
        public static final String ADMIN_ROLE = "#admin";\r
 \r
+       @Deprecated\r
        public static final String FORK_ROLE = "#fork";\r
 \r
+       @Deprecated\r
        public static final String CREATE_ROLE = "#create";\r
 \r
+       @Deprecated\r
        public static final String NOT_FEDERATED_ROLE = "#notfederated";\r
 \r
+       @Deprecated\r
        public static final String NO_ROLE = "#none";\r
 \r
        public static final String EXTERNAL_ACCOUNT = "#externalAccount";\r
@@ -178,6 +183,19 @@ public class Constants {
                return defaultValue;\r
        }\r
 \r
+       public static enum Role {\r
+               NONE, ADMIN, CREATE, FORK, NOT_FEDERATED;\r
+\r
+               public String getRole() {\r
+                       return "#" + name().replace("_", "").toLowerCase();\r
+               }\r
+\r
+               @Override\r
+               public String toString() {\r
+                       return getRole();\r
+               }\r
+       }\r
+\r
        /**\r
         * Enumeration representing the four access restriction levels.\r
         */\r
index 29051df81acc8b6f87a45bf46d8cb76cc1f84ad9..da9a7af72218e6be46c8775db62882b3be06af16 100644 (file)
@@ -21,6 +21,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.IStoredSettings;
 import com.gitblit.manager.IRuntimeManager;
 import com.gitblit.manager.IUserManager;
@@ -138,6 +139,24 @@ public abstract class AuthenticationProvider {
         */
        public abstract boolean supportsTeamMembershipChanges();
 
+       /**
+        * Returns true if the user's role can be changed.
+        *
+        * @param user
+        * @param role
+        * @return true if the user's role can be changed
+        */
+       public abstract boolean supportsRoleChanges(UserModel user, Role role);
+
+       /**
+        * Returns true if the team's role can be changed.
+        *
+        * @param user
+        * @param role
+        * @return true if the team's role can be changed
+        */
+       public abstract boolean supportsRoleChanges(TeamModel team, Role role);
+
     @Override
     public String toString() {
        return getServiceName() + " (" + getClass().getName() + ")";
@@ -199,5 +218,16 @@ public abstract class AuthenticationProvider {
                public boolean supportsTeamMembershipChanges() {
                        return true;
                }
+
+               @Override
+               public boolean supportsRoleChanges(UserModel user, Role role) {
+                       return true;
+               }
+
+               @Override
+               public boolean supportsRoleChanges(TeamModel team, Role role) {
+                       return true;
+               }
+
     }
 }
index 5ffb6930b3a4f758e7c2e74b1d3f98cecb4f300a..2cdabf6f894fc6a3c6b6ecf432e3518ff8583ce4 100644 (file)
@@ -32,8 +32,10 @@ import org.apache.commons.codec.digest.Md5Crypt;
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 
 
@@ -124,6 +126,16 @@ public class HtpasswdAuthProvider extends UsernamePasswordAuthenticationProvider
         return true;
     }
 
+    @Override
+    public boolean supportsRoleChanges(UserModel user, Role role) {
+        return true;
+    }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return true;
+       }
+
     /**
      * Authenticate a user based on a username and password.
      *
index 5690073a99ef6c40fe13b92f8cc6e4e3db396cad..6c97ddf98133b6767ca91d9da251966523259187 100644 (file)
@@ -30,6 +30,7 @@ import java.util.concurrent.TimeUnit;
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
 import com.gitblit.models.TeamModel;
@@ -272,7 +273,6 @@ public class LdapAuthProvider extends UsernamePasswordAuthenticationProvider {
                return StringUtils.isEmpty(settings.getString(Keys.realm.ldap.email, ""));
        }
 
-
        /**
         * If the LDAP server will maintain team memberships then LdapUserService
         * will not allow team membership changes.  In this scenario all team
@@ -286,6 +286,32 @@ public class LdapAuthProvider extends UsernamePasswordAuthenticationProvider {
                return !settings.getBoolean(Keys.realm.ldap.maintainTeams, false);
        }
 
+    @Override
+    public boolean supportsRoleChanges(UserModel user, Role role) {
+       if (Role.ADMIN == role) {
+               if (!supportsTeamMembershipChanges()) {
+                       List<String> admins = settings.getStrings(Keys.realm.ldap.admins);
+                       if (admins.contains(user.username)) {
+                               return false;
+                       }
+               }
+       }
+        return true;
+    }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               if (Role.ADMIN == role) {
+               if (!supportsTeamMembershipChanges()) {
+                       List<String> admins = settings.getStrings(Keys.realm.ldap.admins);
+                       if (admins.contains("@" + team.name)) {
+                               return false;
+                       }
+               }
+       }
+               return true;
+       }
+
        @Override
        public AccountType getAccountType() {
                 return AccountType.LDAP;
index 5d441b8451c66997080f0b55bdbef6ac585fd9e0..46f4dd6a6325438551cf26f42700984a69b70744 100644 (file)
@@ -23,8 +23,10 @@ import org.jvnet.libpam.impl.CLibrary;
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 
 /**
@@ -77,6 +79,16 @@ public class PAMAuthProvider extends UsernamePasswordAuthenticationProvider {
         return true;
     }
 
+    @Override
+    public boolean supportsRoleChanges(UserModel user, Role role) {
+        return true;
+    }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return true;
+       }
+
         @Override
        public AccountType getAccountType() {
                return AccountType.PAM;
index e505a54d37dd6cf0b26e1698fcbc81e73a960bb2..5166fe2255b8aa9173d7ca5d26310f5888ffc1de 100644 (file)
@@ -23,8 +23,10 @@ import org.apache.wicket.util.io.IOUtils;
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.ConnectionUtils;
 import com.gitblit.utils.StringUtils;
@@ -77,6 +79,16 @@ public class RedmineAuthProvider extends UsernamePasswordAuthenticationProvider
         return false;
     }
 
+    @Override
+    public boolean supportsRoleChanges(UserModel user, Role role) {
+        return true;
+    }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return true;
+       }
+
         @Override
        public AccountType getAccountType() {
                return AccountType.REDMINE;
@@ -154,7 +166,7 @@ public class RedmineAuthProvider extends UsernamePasswordAuthenticationProvider
                url = url.concat("/");
         }
         String apiUrl = url + "users/current.json";
-        
+
         HttpURLConnection http;
         if (username == null) {
                // apikey authentication
index e4273ff626e6ad03485215e2d914236d0a321ab9..df033c27a4ba6142ac641e7e68dabbc06f525b35 100644 (file)
@@ -2,8 +2,10 @@ package com.gitblit.auth;
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.sforce.soap.partner.Connector;
 import com.sforce.soap.partner.GetUserInfoResult;
@@ -119,4 +121,15 @@ public class SalesforceAuthProvider extends UsernamePasswordAuthenticationProvid
        public boolean supportsTeamMembershipChanges() {
                return true;
        }
+
+    @Override
+    public boolean supportsRoleChanges(UserModel user, Role role) {
+        return true;
+    }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return true;
+       }
+
 }
index ac15b28fae9a224b37ed1ee50a867f3a32216c02..aee51008a20c32c0a899c4c51d90065d4e451095 100644 (file)
@@ -26,8 +26,10 @@ import waffle.windows.auth.impl.WindowsAuthProviderImpl;
 
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider.UsernamePasswordAuthenticationProvider;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
 import com.sun.jna.platform.win32.Win32Exception;
@@ -90,6 +92,16 @@ public class WindowsAuthProvider extends UsernamePasswordAuthenticationProvider
         return true;
     }
 
+    @Override
+    public boolean supportsRoleChanges(UserModel user, Role role) {
+        return true;
+    }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return true;
+       }
+
         @Override
        public AccountType getAccountType() {
                return AccountType.WINDOWS;
index 6c198fea11ec704dce9b53cbd1c92be86bc7432f..e41deebc46b7b0643e694f4ca4159d554e420398 100644 (file)
@@ -35,6 +35,7 @@ import org.slf4j.LoggerFactory;
 import com.gitblit.Constants;
 import com.gitblit.Constants.AccountType;
 import com.gitblit.Constants.AuthenticationType;
+import com.gitblit.Constants.Role;
 import com.gitblit.IStoredSettings;
 import com.gitblit.Keys;
 import com.gitblit.auth.AuthenticationProvider;
@@ -585,6 +586,28 @@ public class AuthenticationManager implements IAuthenticationManager {
                return (team != null && team.isLocalTeam()) || findProvider(team).supportsTeamMembershipChanges();
        }
 
+       /**
+        * Returns true if the user's role can be changed.
+        *
+        * @param user
+        * @return true if the user's role can be changed
+        */
+       @Override
+       public boolean supportsRoleChanges(UserModel user, Role role) {
+               return (user != null && user.isLocalAccount()) || findProvider(user).supportsRoleChanges(user, role);
+       }
+
+       /**
+        * Returns true if the team's role can be changed.
+        *
+        * @param user
+        * @return true if the team's role can be changed
+        */
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return (team != null && team.isLocalTeam()) || findProvider(team).supportsRoleChanges(team, role);
+       }
+
        protected AuthenticationProvider findProvider(UserModel user) {
                for (AuthenticationProvider provider : authenticationProviders) {
                        if (provider.getAccountType().equals(user.accountType)) {
index 2c883af2a79f2484e852e0c1f25d899d9d027452..09e261fa214aa01afa4a8ebc30082d24aabb71d6 100644 (file)
@@ -51,6 +51,7 @@ import com.gitblit.Constants;
 import com.gitblit.Constants.AccessPermission;
 import com.gitblit.Constants.FederationRequest;
 import com.gitblit.Constants.FederationToken;
+import com.gitblit.Constants.Role;
 import com.gitblit.GitBlitException;
 import com.gitblit.IStoredSettings;
 import com.gitblit.models.FederationModel;
@@ -711,6 +712,16 @@ public class GitblitManager implements IGitblit {
                return authenticationManager.supportsTeamMembershipChanges(team);
        }
 
+       @Override
+       public boolean supportsRoleChanges(UserModel user, Role role) {
+               return authenticationManager.supportsRoleChanges(user, role);
+       }
+
+       @Override
+       public boolean supportsRoleChanges(TeamModel team, Role role) {
+               return authenticationManager.supportsRoleChanges(team, role);
+       }
+
        /*
         * USER MANAGER
         */
index 3600b32575ecd69617c3eafd42272255d189986b..d48ec5344bb46ed58682b5966b940c27def01958 100644 (file)
@@ -18,6 +18,7 @@ package com.gitblit.manager;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.gitblit.Constants.Role;
 import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.transport.ssh.SshKey;
@@ -161,4 +162,22 @@ public interface IAuthenticationManager extends IManager {
         */
        boolean supportsTeamMembershipChanges(TeamModel team);
 
+       /**
+        * Returns true if the specified role can be changed.
+        *
+        * @param user
+        * @return true if the specified role can be changed
+        * @since 1.6.1
+        */
+       boolean supportsRoleChanges(UserModel user, Role role);
+
+       /**
+        * Returns true if the specified role can be changed.
+        *
+        * @param team
+        * @return true if the specified role can be changed
+        * @since 1.6.1
+        */
+       boolean supportsRoleChanges(TeamModel team, Role role);
+
 }
\ No newline at end of file
index 6f13252a2365e3931e7a861d3eba576f8c1bdf22..3093e6353a1dbd708e8427f673a165a4cdaabcd5 100644 (file)
-/*\r
- * Copyright 2011 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.servlet;\r
-\r
-import java.io.IOException;\r
-import java.security.Principal;\r
-import java.util.Enumeration;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import javax.servlet.Filter;\r
-import javax.servlet.FilterChain;\r
-import javax.servlet.FilterConfig;\r
-import javax.servlet.ServletException;\r
-import javax.servlet.ServletRequest;\r
-import javax.servlet.ServletResponse;\r
-import javax.servlet.http.HttpServletRequest;\r
-import javax.servlet.http.HttpServletRequestWrapper;\r
-import javax.servlet.http.HttpServletResponse;\r
-import javax.servlet.http.HttpSession;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import com.gitblit.Constants;\r
-import com.gitblit.manager.IAuthenticationManager;\r
-import com.gitblit.models.UserModel;\r
-import com.gitblit.utils.DeepCopier;\r
-import com.gitblit.utils.StringUtils;\r
-\r
-/**\r
- * The AuthenticationFilter is a servlet filter that preprocesses requests that\r
- * match its url pattern definition in the web.xml file.\r
- *\r
- * http://en.wikipedia.org/wiki/Basic_access_authentication\r
- *\r
- * @author James Moger\r
- *\r
- */\r
-public abstract class AuthenticationFilter implements Filter {\r
-\r
-       protected static final String CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";\r
-\r
-       protected static final String SESSION_SECURED = "com.gitblit.secured";\r
-\r
-       protected transient Logger logger = LoggerFactory.getLogger(getClass());\r
-\r
-       protected IAuthenticationManager authenticationManager;\r
-\r
-       protected AuthenticationFilter(IAuthenticationManager authenticationManager) {\r
-               this.authenticationManager = authenticationManager;\r
-       }\r
-\r
-       @Override\r
-       public void init(FilterConfig filterConfig) throws ServletException {\r
-       }\r
-\r
-       @Override\r
-       public void destroy() {\r
-       }\r
-\r
-       /**\r
-        * doFilter does the actual work of preprocessing the request to ensure that\r
-        * the user may proceed.\r
-        *\r
-        * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,\r
-        *      javax.servlet.ServletResponse, javax.servlet.FilterChain)\r
-        */\r
-       @Override\r
-       public abstract void doFilter(final ServletRequest request, final ServletResponse response,\r
-                       final FilterChain chain) throws IOException, ServletException;\r
-\r
-       /**\r
-        * Allow the filter to require a client certificate to continue processing.\r
-        *\r
-        * @return true, if a client certificate is required\r
-        */\r
-       protected boolean requiresClientCertificate() {\r
-               return false;\r
-       }\r
-\r
-       /**\r
-        * Returns the full relative url of the request.\r
-        *\r
-        * @param httpRequest\r
-        * @return url\r
-        */\r
-       protected String getFullUrl(HttpServletRequest httpRequest) {\r
-               String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath();\r
-               String url = httpRequest.getRequestURI().substring(servletUrl.length());\r
-               String params = httpRequest.getQueryString();\r
-               if (url.length() > 0 && url.charAt(0) == '/') {\r
-                       url = url.substring(1);\r
-               }\r
-               String fullUrl = url + (StringUtils.isEmpty(params) ? "" : ("?" + params));\r
-               return fullUrl;\r
-       }\r
-\r
-       /**\r
-        * Returns the user making the request, if the user has authenticated.\r
-        *\r
-        * @param httpRequest\r
-        * @return user\r
-        */\r
-       protected UserModel getUser(HttpServletRequest httpRequest) {\r
-               UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate());\r
-               return user;\r
-       }\r
-\r
-       /**\r
-        * Taken from Jetty's LoginAuthenticator.renewSessionOnAuthentication()\r
-        */\r
-       protected void newSession(HttpServletRequest request, HttpServletResponse response) {\r
-               HttpSession oldSession = request.getSession(false);\r
-               if (oldSession != null && oldSession.getAttribute(SESSION_SECURED) == null) {\r
-                       synchronized (this) {\r
-                               Map<String, Object> attributes = new HashMap<String, Object>();\r
-                               Enumeration<String> e = oldSession.getAttributeNames();\r
-                               while (e.hasMoreElements()) {\r
-                                       String name = e.nextElement();\r
-                                       attributes.put(name, oldSession.getAttribute(name));\r
-                                       oldSession.removeAttribute(name);\r
-                               }\r
-                               oldSession.invalidate();\r
-\r
-                               HttpSession newSession = request.getSession(true);\r
-                               newSession.setAttribute(SESSION_SECURED, Boolean.TRUE);\r
-                               for (Map.Entry<String, Object> entry : attributes.entrySet()) {\r
-                                       newSession.setAttribute(entry.getKey(), entry.getValue());\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Wraps a standard HttpServletRequest and overrides user principal methods.\r
-        */\r
-       public static class AuthenticatedRequest extends HttpServletRequestWrapper {\r
-\r
-               private UserModel user;\r
-\r
-               public AuthenticatedRequest(HttpServletRequest req) {\r
-                       super(req);\r
-                       user = DeepCopier.copy(UserModel.ANONYMOUS);\r
-               }\r
-\r
-               UserModel getUser() {\r
-                       return user;\r
-               }\r
-\r
-               void setUser(UserModel user) {\r
-                       this.user = user;\r
-               }\r
-\r
-               @Override\r
-               public String getRemoteUser() {\r
-                       return user.username;\r
-               }\r
-\r
-               @Override\r
-               public boolean isUserInRole(String role) {\r
-                       if (role.equals(Constants.ADMIN_ROLE)) {\r
-                               return user.canAdmin();\r
-                       }\r
-                       // Gitblit does not currently use actual roles in the traditional\r
-                       // servlet container sense.  That is the reason this is marked\r
-                       // deprecated, but I may want to revisit this.\r
-                       return user.hasRepositoryPermission(role);\r
-               }\r
-\r
-               @Override\r
-               public Principal getUserPrincipal() {\r
-                       return user;\r
-               }\r
-       }\r
-}\r
+/*
+ * Copyright 2011 gitblit.com.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.gitblit.servlet;
+
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.Constants;
+import com.gitblit.Constants.Role;
+import com.gitblit.manager.IAuthenticationManager;
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.DeepCopier;
+import com.gitblit.utils.StringUtils;
+
+/**
+ * The AuthenticationFilter is a servlet filter that preprocesses requests that
+ * match its url pattern definition in the web.xml file.
+ *
+ * http://en.wikipedia.org/wiki/Basic_access_authentication
+ *
+ * @author James Moger
+ *
+ */
+public abstract class AuthenticationFilter implements Filter {
+
+       protected static final String CHALLENGE = "Basic realm=\"" + Constants.NAME + "\"";
+
+       protected static final String SESSION_SECURED = "com.gitblit.secured";
+
+       protected transient Logger logger = LoggerFactory.getLogger(getClass());
+
+       protected IAuthenticationManager authenticationManager;
+
+       protected AuthenticationFilter(IAuthenticationManager authenticationManager) {
+               this.authenticationManager = authenticationManager;
+       }
+
+       @Override
+       public void init(FilterConfig filterConfig) throws ServletException {
+       }
+
+       @Override
+       public void destroy() {
+       }
+
+       /**
+        * doFilter does the actual work of preprocessing the request to ensure that
+        * the user may proceed.
+        *
+        * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
+        *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
+        */
+       @Override
+       public abstract void doFilter(final ServletRequest request, final ServletResponse response,
+                       final FilterChain chain) throws IOException, ServletException;
+
+       /**
+        * Allow the filter to require a client certificate to continue processing.
+        *
+        * @return true, if a client certificate is required
+        */
+       protected boolean requiresClientCertificate() {
+               return false;
+       }
+
+       /**
+        * Returns the full relative url of the request.
+        *
+        * @param httpRequest
+        * @return url
+        */
+       protected String getFullUrl(HttpServletRequest httpRequest) {
+               String servletUrl = httpRequest.getContextPath() + httpRequest.getServletPath();
+               String url = httpRequest.getRequestURI().substring(servletUrl.length());
+               String params = httpRequest.getQueryString();
+               if (url.length() > 0 && url.charAt(0) == '/') {
+                       url = url.substring(1);
+               }
+               String fullUrl = url + (StringUtils.isEmpty(params) ? "" : ("?" + params));
+               return fullUrl;
+       }
+
+       /**
+        * Returns the user making the request, if the user has authenticated.
+        *
+        * @param httpRequest
+        * @return user
+        */
+       protected UserModel getUser(HttpServletRequest httpRequest) {
+               UserModel user = authenticationManager.authenticate(httpRequest, requiresClientCertificate());
+               return user;
+       }
+
+       /**
+        * Taken from Jetty's LoginAuthenticator.renewSessionOnAuthentication()
+        */
+       protected void newSession(HttpServletRequest request, HttpServletResponse response) {
+               HttpSession oldSession = request.getSession(false);
+               if (oldSession != null && oldSession.getAttribute(SESSION_SECURED) == null) {
+                       synchronized (this) {
+                               Map<String, Object> attributes = new HashMap<String, Object>();
+                               Enumeration<String> e = oldSession.getAttributeNames();
+                               while (e.hasMoreElements()) {
+                                       String name = e.nextElement();
+                                       attributes.put(name, oldSession.getAttribute(name));
+                                       oldSession.removeAttribute(name);
+                               }
+                               oldSession.invalidate();
+
+                               HttpSession newSession = request.getSession(true);
+                               newSession.setAttribute(SESSION_SECURED, Boolean.TRUE);
+                               for (Map.Entry<String, Object> entry : attributes.entrySet()) {
+                                       newSession.setAttribute(entry.getKey(), entry.getValue());
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Wraps a standard HttpServletRequest and overrides user principal methods.
+        */
+       public static class AuthenticatedRequest extends HttpServletRequestWrapper {
+
+               private UserModel user;
+
+               public AuthenticatedRequest(HttpServletRequest req) {
+                       super(req);
+                       user = DeepCopier.copy(UserModel.ANONYMOUS);
+               }
+
+               UserModel getUser() {
+                       return user;
+               }
+
+               void setUser(UserModel user) {
+                       this.user = user;
+               }
+
+               @Override
+               public String getRemoteUser() {
+                       return user.username;
+               }
+
+               @Override
+               public boolean isUserInRole(String role) {
+                       if (role.equals(Role.ADMIN.getRole())) {
+                               return user.canAdmin();
+                       }
+                       // Gitblit does not currently use actual roles in the traditional
+                       // servlet container sense.  That is the reason this is marked
+                       // deprecated, but I may want to revisit this.
+                       return user.hasRepositoryPermission(role);
+               }
+
+               @Override
+               public Principal getUserPrincipal() {
+                       return user;
+               }
+       }
+}
index f537f33de121d0287ee5eaae015adf20295fcbc7..a43d8db05122a3c1c9568d7aab7daacff2ecd788 100644 (file)
@@ -39,6 +39,7 @@ import org.apache.wicket.model.util.CollectionModel;
 import org.apache.wicket.model.util.ListModel;\r
 \r
 import com.gitblit.Constants.RegistrantType;\r
+import com.gitblit.Constants.Role;\r
 import com.gitblit.GitBlitException;\r
 import com.gitblit.Keys;\r
 import com.gitblit.models.RegistrantAccessPermission;\r
@@ -221,14 +222,23 @@ public class EditTeamPage extends RootSubPage {
                // do not let the browser pre-populate these fields\r
                form.add(new SimpleAttributeModifier("autocomplete", "off"));\r
 \r
-               // not all user services support manipulating team memberships\r
+               // not all user providers support manipulating team memberships\r
                boolean editMemberships = app().authentication().supportsTeamMembershipChanges(teamModel);\r
 \r
+               // not all user providers support manipulating the admin role\r
+               boolean changeAdminRole = app().authentication().supportsRoleChanges(teamModel, Role.ADMIN);\r
+\r
+               // not all user providers support manipulating the create role\r
+               boolean changeCreateRole = app().authentication().supportsRoleChanges(teamModel, Role.CREATE);\r
+\r
+               // not all user providers support manipulating the fork role\r
+               boolean changeForkRole = app().authentication().supportsRoleChanges(teamModel, Role.FORK);\r
+\r
                // field names reflective match TeamModel fields\r
                form.add(new TextField<String>("name"));\r
-               form.add(new CheckBox("canAdmin"));\r
-               form.add(new CheckBox("canFork").setEnabled(app().settings().getBoolean(Keys.web.allowForking, true)));\r
-               form.add(new CheckBox("canCreate"));\r
+               form.add(new CheckBox("canAdmin").setEnabled(changeAdminRole));\r
+               form.add(new CheckBox("canFork").setEnabled(app().settings().getBoolean(Keys.web.allowForking, true) && changeForkRole));\r
+               form.add(new CheckBox("canCreate").setEnabled(changeCreateRole));\r
                form.add(users.setEnabled(editMemberships));\r
                mailingLists = new Model<String>(teamModel.mailingLists == null ? ""\r
                                : StringUtils.flattenStrings(teamModel.mailingLists, " "));\r
index 454aa619164225fd8bb36c1415e25d1e8b8c6ff6..5ee2f9fd79b7076ae80e06c18842c8c3382d6d48 100644 (file)
@@ -35,6 +35,7 @@ import org.apache.wicket.model.util.CollectionModel;
 import org.apache.wicket.model.util.ListModel;\r
 \r
 import com.gitblit.Constants.RegistrantType;\r
+import com.gitblit.Constants.Role;\r
 import com.gitblit.GitBlitException;\r
 import com.gitblit.Keys;\r
 import com.gitblit.models.RegistrantAccessPermission;\r
@@ -216,18 +217,27 @@ public class EditUserPage extends RootSubPage {
                // do not let the browser pre-populate these fields\r
                form.add(new SimpleAttributeModifier("autocomplete", "off"));\r
 \r
-               // not all user services support manipulating username and password\r
+               // not all user providers support manipulating username and password\r
                boolean editCredentials = app().authentication().supportsCredentialChanges(userModel);\r
 \r
-               // not all user services support manipulating display name\r
+               // not all user providers support manipulating display name\r
                boolean editDisplayName = app().authentication().supportsDisplayNameChanges(userModel);\r
 \r
-               // not all user services support manipulating email address\r
+               // not all user providers support manipulating email address\r
                boolean editEmailAddress = app().authentication().supportsEmailAddressChanges(userModel);\r
 \r
-               // not all user services support manipulating team memberships\r
+               // not all user providers support manipulating team memberships\r
                boolean editTeams = app().authentication().supportsTeamMembershipChanges(userModel);\r
 \r
+               // not all user providers support manipulating the admin role\r
+               boolean changeAdminRole = app().authentication().supportsRoleChanges(userModel, Role.ADMIN);\r
+\r
+               // not all user providers support manipulating the create role\r
+               boolean changeCreateRole = app().authentication().supportsRoleChanges(userModel, Role.CREATE);\r
+\r
+               // not all user providers support manipulating the fork role\r
+               boolean changeForkRole = app().authentication().supportsRoleChanges(userModel, Role.FORK);\r
+\r
                // field names reflective match UserModel fields\r
                form.add(new TextField<String>("username").setEnabled(editCredentials));\r
                PasswordTextField passwordField = new PasswordTextField("password");\r
@@ -245,7 +255,7 @@ public class EditUserPage extends RootSubPage {
                        // display a disabled-yet-checked checkbox\r
                        form.add(new CheckBox("canAdmin", Model.of(true)).setEnabled(false));\r
                } else {\r
-                       form.add(new CheckBox("canAdmin"));\r
+                       form.add(new CheckBox("canAdmin").setEnabled(changeAdminRole));\r
                }\r
 \r
                if (userModel.canFork() && !userModel.canFork) {\r
@@ -254,7 +264,7 @@ public class EditUserPage extends RootSubPage {
                        form.add(new CheckBox("canFork", Model.of(true)).setEnabled(false));\r
                } else {\r
                        final boolean forkingAllowed = app().settings().getBoolean(Keys.web.allowForking, true);\r
-                       form.add(new CheckBox("canFork").setEnabled(forkingAllowed));\r
+                       form.add(new CheckBox("canFork").setEnabled(forkingAllowed && changeForkRole));\r
                }\r
 \r
                if (userModel.canCreate() && !userModel.canCreate) {\r
@@ -262,7 +272,7 @@ public class EditUserPage extends RootSubPage {
                        // display a disabled-yet-checked checkbox\r
                        form.add(new CheckBox("canCreate", Model.of(true)).setEnabled(false));\r
                } else {\r
-                       form.add(new CheckBox("canCreate"));\r
+                       form.add(new CheckBox("canCreate").setEnabled(changeCreateRole));\r
                }\r
 \r
                form.add(new CheckBox("excludeFromFederation"));\r