diff options
author | James Moger <james.moger@gitblit.com> | 2014-09-25 12:15:27 -0400 |
---|---|---|
committer | James Moger <james.moger@gitblit.com> | 2014-09-26 09:11:20 -0400 |
commit | 6e3481850db665f9cafc9a554a748e3c9cbd50f5 (patch) | |
tree | 1aecf7437204b5cfd03cbfbef093e4b2442e49e5 /src | |
parent | ba04d6d62e443cbd23c0544094aa2e55d01b2d0f (diff) | |
download | gitblit-6e3481850db665f9cafc9a554a748e3c9cbd50f5.tar.gz gitblit-6e3481850db665f9cafc9a554a748e3c9cbd50f5.zip |
Allow authentication providers to control user and team role changes
Diffstat (limited to 'src')
15 files changed, 428 insertions, 218 deletions
diff --git a/src/main/java/com/gitblit/ConfigUserService.java b/src/main/java/com/gitblit/ConfigUserService.java index d7d6c14f..200ec8a6 100644 --- a/src/main/java/com/gitblit/ConfigUserService.java +++ b/src/main/java/com/gitblit/ConfigUserService.java @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory; import com.gitblit.Constants.AccessPermission;
import com.gitblit.Constants.AccountType;
+import com.gitblit.Constants.Role;
import com.gitblit.Constants.Transport;
import com.gitblit.manager.IRuntimeManager;
import com.gitblit.models.TeamModel;
@@ -734,22 +735,22 @@ public class ConfigUserService implements IUserService { // user roles
List<String> roles = new ArrayList<String>();
if (model.canAdmin) {
- roles.add(Constants.ADMIN_ROLE);
+ roles.add(Role.ADMIN.getRole());
}
if (model.canFork) {
- roles.add(Constants.FORK_ROLE);
+ roles.add(Role.FORK.getRole());
}
if (model.canCreate) {
- roles.add(Constants.CREATE_ROLE);
+ roles.add(Role.CREATE.getRole());
}
if (model.excludeFromFederation) {
- roles.add(Constants.NOT_FEDERATED_ROLE);
+ roles.add(Role.NOT_FEDERATED.getRole());
}
if (roles.size() == 0) {
// we do this to ensure that user record with no password
// is written. otherwise, StoredConfig optimizes that account
// away. :(
- roles.add(Constants.NO_ROLE);
+ roles.add(Role.NONE.getRole());
}
config.setStringList(USER, model.username, ROLE, roles);
@@ -778,18 +779,18 @@ public class ConfigUserService implements IUserService { // team roles
List<String> roles = new ArrayList<String>();
if (model.canAdmin) {
- roles.add(Constants.ADMIN_ROLE);
+ roles.add(Role.ADMIN.getRole());
}
if (model.canFork) {
- roles.add(Constants.FORK_ROLE);
+ roles.add(Role.FORK.getRole());
}
if (model.canCreate) {
- roles.add(Constants.CREATE_ROLE);
+ roles.add(Role.CREATE.getRole());
}
if (roles.size() == 0) {
// we do this to ensure that team record is written.
// Otherwise, StoredConfig might optimizes that record away.
- roles.add(Constants.NO_ROLE);
+ roles.add(Role.NONE.getRole());
}
config.setStringList(TEAM, model.name, ROLE, roles);
if (model.accountType != null) {
@@ -911,10 +912,10 @@ public class ConfigUserService implements IUserService { // user roles
Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(
USER, username, ROLE)));
- user.canAdmin = roles.contains(Constants.ADMIN_ROLE);
- user.canFork = roles.contains(Constants.FORK_ROLE);
- user.canCreate = roles.contains(Constants.CREATE_ROLE);
- user.excludeFromFederation = roles.contains(Constants.NOT_FEDERATED_ROLE);
+ user.canAdmin = roles.contains(Role.ADMIN.getRole());
+ user.canFork = roles.contains(Role.FORK.getRole());
+ user.canCreate = roles.contains(Role.CREATE.getRole());
+ user.excludeFromFederation = roles.contains(Role.NOT_FEDERATED.getRole());
// repository memberships
if (!user.canAdmin) {
@@ -947,9 +948,9 @@ public class ConfigUserService implements IUserService { TeamModel team = new TeamModel(teamname);
Set<String> roles = new HashSet<String>(Arrays.asList(config.getStringList(
TEAM, teamname, ROLE)));
- team.canAdmin = roles.contains(Constants.ADMIN_ROLE);
- team.canFork = roles.contains(Constants.FORK_ROLE);
- team.canCreate = roles.contains(Constants.CREATE_ROLE);
+ team.canAdmin = roles.contains(Role.ADMIN.getRole());
+ team.canFork = roles.contains(Role.FORK.getRole());
+ team.canCreate = roles.contains(Role.CREATE.getRole());
team.accountType = AccountType.fromString(config.getString(TEAM, teamname, ACCOUNTTYPE));
if (!team.canAdmin) {
diff --git a/src/main/java/com/gitblit/Constants.java b/src/main/java/com/gitblit/Constants.java index 279d3c92..aaa6e69c 100644 --- a/src/main/java/com/gitblit/Constants.java +++ b/src/main/java/com/gitblit/Constants.java @@ -36,14 +36,19 @@ public class Constants { public static final String FULL_NAME = "Gitblit - a pure Java Git solution";
+ @Deprecated
public static final String ADMIN_ROLE = "#admin";
+ @Deprecated
public static final String FORK_ROLE = "#fork";
+ @Deprecated
public static final String CREATE_ROLE = "#create";
+ @Deprecated
public static final String NOT_FEDERATED_ROLE = "#notfederated";
+ @Deprecated
public static final String NO_ROLE = "#none";
public static final String EXTERNAL_ACCOUNT = "#externalAccount";
@@ -178,6 +183,19 @@ public class Constants { return defaultValue;
}
+ public static enum Role {
+ NONE, ADMIN, CREATE, FORK, NOT_FEDERATED;
+
+ public String getRole() {
+ return "#" + name().replace("_", "").toLowerCase();
+ }
+
+ @Override
+ public String toString() {
+ return getRole();
+ }
+ }
+
/**
* Enumeration representing the four access restriction levels.
*/
diff --git a/src/main/java/com/gitblit/auth/AuthenticationProvider.java b/src/main/java/com/gitblit/auth/AuthenticationProvider.java index 29051df8..da9a7af7 100644 --- a/src/main/java/com/gitblit/auth/AuthenticationProvider.java +++ b/src/main/java/com/gitblit/auth/AuthenticationProvider.java @@ -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; + } + } } diff --git a/src/main/java/com/gitblit/auth/HtpasswdAuthProvider.java b/src/main/java/com/gitblit/auth/HtpasswdAuthProvider.java index 5ffb6930..2cdabf6f 100644 --- a/src/main/java/com/gitblit/auth/HtpasswdAuthProvider.java +++ b/src/main/java/com/gitblit/auth/HtpasswdAuthProvider.java @@ -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. * diff --git a/src/main/java/com/gitblit/auth/LdapAuthProvider.java b/src/main/java/com/gitblit/auth/LdapAuthProvider.java index 5690073a..6c97ddf9 100644 --- a/src/main/java/com/gitblit/auth/LdapAuthProvider.java +++ b/src/main/java/com/gitblit/auth/LdapAuthProvider.java @@ -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; diff --git a/src/main/java/com/gitblit/auth/PAMAuthProvider.java b/src/main/java/com/gitblit/auth/PAMAuthProvider.java index 5d441b84..46f4dd6a 100644 --- a/src/main/java/com/gitblit/auth/PAMAuthProvider.java +++ b/src/main/java/com/gitblit/auth/PAMAuthProvider.java @@ -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; diff --git a/src/main/java/com/gitblit/auth/RedmineAuthProvider.java b/src/main/java/com/gitblit/auth/RedmineAuthProvider.java index e505a54d..5166fe22 100644 --- a/src/main/java/com/gitblit/auth/RedmineAuthProvider.java +++ b/src/main/java/com/gitblit/auth/RedmineAuthProvider.java @@ -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 diff --git a/src/main/java/com/gitblit/auth/SalesforceAuthProvider.java b/src/main/java/com/gitblit/auth/SalesforceAuthProvider.java index e4273ff6..df033c27 100644 --- a/src/main/java/com/gitblit/auth/SalesforceAuthProvider.java +++ b/src/main/java/com/gitblit/auth/SalesforceAuthProvider.java @@ -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; + } + } diff --git a/src/main/java/com/gitblit/auth/WindowsAuthProvider.java b/src/main/java/com/gitblit/auth/WindowsAuthProvider.java index ac15b28f..aee51008 100644 --- a/src/main/java/com/gitblit/auth/WindowsAuthProvider.java +++ b/src/main/java/com/gitblit/auth/WindowsAuthProvider.java @@ -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; diff --git a/src/main/java/com/gitblit/manager/AuthenticationManager.java b/src/main/java/com/gitblit/manager/AuthenticationManager.java index 6c198fea..e41deebc 100644 --- a/src/main/java/com/gitblit/manager/AuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/AuthenticationManager.java @@ -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)) { diff --git a/src/main/java/com/gitblit/manager/GitblitManager.java b/src/main/java/com/gitblit/manager/GitblitManager.java index 2c883af2..09e261fa 100644 --- a/src/main/java/com/gitblit/manager/GitblitManager.java +++ b/src/main/java/com/gitblit/manager/GitblitManager.java @@ -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 */ diff --git a/src/main/java/com/gitblit/manager/IAuthenticationManager.java b/src/main/java/com/gitblit/manager/IAuthenticationManager.java index 3600b325..d48ec534 100644 --- a/src/main/java/com/gitblit/manager/IAuthenticationManager.java +++ b/src/main/java/com/gitblit/manager/IAuthenticationManager.java @@ -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 diff --git a/src/main/java/com/gitblit/servlet/AuthenticationFilter.java b/src/main/java/com/gitblit/servlet/AuthenticationFilter.java index 6f13252a..3093e635 100644 --- a/src/main/java/com/gitblit/servlet/AuthenticationFilter.java +++ b/src/main/java/com/gitblit/servlet/AuthenticationFilter.java @@ -1,189 +1,190 @@ -/*
- * 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.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(Constants.ADMIN_ROLE)) {
- 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;
- }
- }
-}
+/* + * 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; + } + } +} diff --git a/src/main/java/com/gitblit/wicket/pages/EditTeamPage.java b/src/main/java/com/gitblit/wicket/pages/EditTeamPage.java index f537f33d..a43d8db0 100644 --- a/src/main/java/com/gitblit/wicket/pages/EditTeamPage.java +++ b/src/main/java/com/gitblit/wicket/pages/EditTeamPage.java @@ -39,6 +39,7 @@ import org.apache.wicket.model.util.CollectionModel; import org.apache.wicket.model.util.ListModel;
import com.gitblit.Constants.RegistrantType;
+import com.gitblit.Constants.Role;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
import com.gitblit.models.RegistrantAccessPermission;
@@ -221,14 +222,23 @@ public class EditTeamPage extends RootSubPage { // do not let the browser pre-populate these fields
form.add(new SimpleAttributeModifier("autocomplete", "off"));
- // not all user services support manipulating team memberships
+ // not all user providers support manipulating team memberships
boolean editMemberships = app().authentication().supportsTeamMembershipChanges(teamModel);
+ // not all user providers support manipulating the admin role
+ boolean changeAdminRole = app().authentication().supportsRoleChanges(teamModel, Role.ADMIN);
+
+ // not all user providers support manipulating the create role
+ boolean changeCreateRole = app().authentication().supportsRoleChanges(teamModel, Role.CREATE);
+
+ // not all user providers support manipulating the fork role
+ boolean changeForkRole = app().authentication().supportsRoleChanges(teamModel, Role.FORK);
+
// field names reflective match TeamModel fields
form.add(new TextField<String>("name"));
- form.add(new CheckBox("canAdmin"));
- form.add(new CheckBox("canFork").setEnabled(app().settings().getBoolean(Keys.web.allowForking, true)));
- form.add(new CheckBox("canCreate"));
+ form.add(new CheckBox("canAdmin").setEnabled(changeAdminRole));
+ form.add(new CheckBox("canFork").setEnabled(app().settings().getBoolean(Keys.web.allowForking, true) && changeForkRole));
+ form.add(new CheckBox("canCreate").setEnabled(changeCreateRole));
form.add(users.setEnabled(editMemberships));
mailingLists = new Model<String>(teamModel.mailingLists == null ? ""
: StringUtils.flattenStrings(teamModel.mailingLists, " "));
diff --git a/src/main/java/com/gitblit/wicket/pages/EditUserPage.java b/src/main/java/com/gitblit/wicket/pages/EditUserPage.java index 454aa619..5ee2f9fd 100644 --- a/src/main/java/com/gitblit/wicket/pages/EditUserPage.java +++ b/src/main/java/com/gitblit/wicket/pages/EditUserPage.java @@ -35,6 +35,7 @@ import org.apache.wicket.model.util.CollectionModel; import org.apache.wicket.model.util.ListModel;
import com.gitblit.Constants.RegistrantType;
+import com.gitblit.Constants.Role;
import com.gitblit.GitBlitException;
import com.gitblit.Keys;
import com.gitblit.models.RegistrantAccessPermission;
@@ -216,18 +217,27 @@ public class EditUserPage extends RootSubPage { // do not let the browser pre-populate these fields
form.add(new SimpleAttributeModifier("autocomplete", "off"));
- // not all user services support manipulating username and password
+ // not all user providers support manipulating username and password
boolean editCredentials = app().authentication().supportsCredentialChanges(userModel);
- // not all user services support manipulating display name
+ // not all user providers support manipulating display name
boolean editDisplayName = app().authentication().supportsDisplayNameChanges(userModel);
- // not all user services support manipulating email address
+ // not all user providers support manipulating email address
boolean editEmailAddress = app().authentication().supportsEmailAddressChanges(userModel);
- // not all user services support manipulating team memberships
+ // not all user providers support manipulating team memberships
boolean editTeams = app().authentication().supportsTeamMembershipChanges(userModel);
+ // not all user providers support manipulating the admin role
+ boolean changeAdminRole = app().authentication().supportsRoleChanges(userModel, Role.ADMIN);
+
+ // not all user providers support manipulating the create role
+ boolean changeCreateRole = app().authentication().supportsRoleChanges(userModel, Role.CREATE);
+
+ // not all user providers support manipulating the fork role
+ boolean changeForkRole = app().authentication().supportsRoleChanges(userModel, Role.FORK);
+
// field names reflective match UserModel fields
form.add(new TextField<String>("username").setEnabled(editCredentials));
PasswordTextField passwordField = new PasswordTextField("password");
@@ -245,7 +255,7 @@ public class EditUserPage extends RootSubPage { // display a disabled-yet-checked checkbox
form.add(new CheckBox("canAdmin", Model.of(true)).setEnabled(false));
} else {
- form.add(new CheckBox("canAdmin"));
+ form.add(new CheckBox("canAdmin").setEnabled(changeAdminRole));
}
if (userModel.canFork() && !userModel.canFork) {
@@ -254,7 +264,7 @@ public class EditUserPage extends RootSubPage { form.add(new CheckBox("canFork", Model.of(true)).setEnabled(false));
} else {
final boolean forkingAllowed = app().settings().getBoolean(Keys.web.allowForking, true);
- form.add(new CheckBox("canFork").setEnabled(forkingAllowed));
+ form.add(new CheckBox("canFork").setEnabled(forkingAllowed && changeForkRole));
}
if (userModel.canCreate() && !userModel.canCreate) {
@@ -262,7 +272,7 @@ public class EditUserPage extends RootSubPage { // display a disabled-yet-checked checkbox
form.add(new CheckBox("canCreate", Model.of(true)).setEnabled(false));
} else {
- form.add(new CheckBox("canCreate"));
+ form.add(new CheckBox("canCreate").setEnabled(changeCreateRole));
}
form.add(new CheckBox("excludeFromFederation"));
|