diff --git a/scm-core/src/main/java/sonia/scm/User.java b/scm-core/src/main/java/sonia/scm/User.java new file mode 100644 index 0000000000..fd2c5bf7c3 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/User.java @@ -0,0 +1,139 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + + + +package sonia.scm; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + +import java.security.Principal; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "users") +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(propOrder = { "name", "displayName", "mail" }) +public class User implements Principal, Serializable +{ + + /** Field description */ + private static final long serialVersionUID = -3089541936726329663L; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + */ + public User() {} + + /** + * Constructs ... + * + * + * @param name + * @param displayName + * @param mail + */ + public User(String name, String displayName, String mail) + { + this.name = name; + this.displayName = displayName; + this.mail = mail; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getDisplayName() + { + return displayName; + } + + /** + * Method description + * + * + * @return + */ + public String getMail() + { + return mail; + } + + /** + * Method description + * + * + * @return + */ + @Override + public String getName() + { + return name; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param displayName + */ + public void setDisplayName(String displayName) + { + this.displayName = displayName; + } + + /** + * Method description + * + * + * @param mail + */ + public void setMail(String mail) + { + this.mail = mail; + } + + /** + * Method description + * + * + * + * @param name + */ + public void setName(String name) + { + this.name = name; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String displayName; + + /** Field description */ + private String mail; + + /** Field description */ + private String name; +} diff --git a/scm-webapp/src/main/java/sonia/scm/ScmState.java b/scm-webapp/src/main/java/sonia/scm/ScmState.java index b97bd6a802..23d6332051 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmState.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmState.java @@ -29,6 +29,19 @@ public class ScmState */ public ScmState() {} + /** + * Constructs ... + * + * + * @param user + * @param repositoryTypes + */ + public ScmState(User user, RepositoryType[] repositoryTypes) + { + this.user = user; + this.repositoryTypes = repositoryTypes; + } + //~--- get methods ---------------------------------------------------------- /** @@ -48,9 +61,9 @@ public class ScmState * * @return */ - public String getUsername() + public User getUser() { - return username; + return user; } /** @@ -92,11 +105,11 @@ public class ScmState * Method description * * - * @param username + * @param user */ - public void setUsername(String username) + public void setUser(User user) { - this.username = username; + this.user = user; } //~--- fields --------------------------------------------------------------- @@ -109,5 +122,5 @@ public class ScmState private boolean success = true; /** Field description */ - private String username; + private User user; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java index 6114f0a5f6..010a1c1097 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java @@ -11,9 +11,12 @@ package sonia.scm.api.rest.resources; import sonia.scm.RepositoryType; import sonia.scm.ScmState; +import sonia.scm.User; +import sonia.scm.security.Authenticator; //~--- JDK imports ------------------------------------------------------------ +import javax.inject.Inject; import javax.inject.Singleton; import javax.servlet.http.HttpServletRequest; @@ -38,6 +41,15 @@ import javax.ws.rs.core.Response; public class AuthenticationResource { + /** Field description */ + private static final RepositoryType[] types = new RepositoryType[] { + new RepositoryType("hg", + "Mercurial"), + new RepositoryType("svn", "Subversion"), + new RepositoryType("git", "Git") }; + + //~--- get methods ---------------------------------------------------------- + /** * Method description * @@ -54,11 +66,11 @@ public class AuthenticationResource @FormParam("password") String password) { ScmState state = null; + User user = authenticator.authenticate(request, username, password); - if ("hans".equals(username) && "hans123".equals(password)) + if (user != null) { - request.getSession(true).setAttribute("auth", username); - state = getState(username); + state = getState(user); } else { @@ -80,11 +92,11 @@ public class AuthenticationResource public ScmState getState(@Context HttpServletRequest request) { ScmState state = null; - String username = (String) request.getSession(true).getAttribute("auth"); + User user = authenticator.getUser(request); - if (username != null) + if (user != null) { - state = getState(username); + state = getState(user); } else { @@ -98,23 +110,24 @@ public class AuthenticationResource * Method description * * - * @param username + * + * @param user * * @return */ - private ScmState getState(String username) + private ScmState getState(User user) { ScmState state = new ScmState(); - state.setUsername(username); - - RepositoryType[] types = new RepositoryType[] { - new RepositoryType("hg", "Mercurial"), - new RepositoryType("svn", "Subversion"), - new RepositoryType("git", "Git") }; - + state.setUser(user); state.setRepositoryTypes(types); return state; } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @Inject + private Authenticator authenticator; } diff --git a/scm-webapp/src/main/java/sonia/scm/security/Authenticator.java b/scm-webapp/src/main/java/sonia/scm/security/Authenticator.java new file mode 100644 index 0000000000..f09bdde1b1 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/security/Authenticator.java @@ -0,0 +1,49 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.User; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.servlet.http.HttpServletRequest; + +/** + * + * @author Sebastian Sdorra + */ +public interface Authenticator +{ + + /** + * Method description + * + * + * @param request + * @param username + * @param password + * + * @return + */ + public User authenticate(HttpServletRequest request, String username, + String password); + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + */ + public User getUser(HttpServletRequest request); +} diff --git a/scm-webapp/src/main/java/sonia/scm/security/DemoAuthenticator.java b/scm-webapp/src/main/java/sonia/scm/security/DemoAuthenticator.java new file mode 100644 index 0000000000..c96f4f1259 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/security/DemoAuthenticator.java @@ -0,0 +1,91 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.User; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +/** + * + * @author Sebastian Sdorra + */ +public class DemoAuthenticator implements Authenticator +{ + + /** Field description */ + private static final String DEMO_DISPLAYNAME = "Hans am Schalter"; + + /** Field description */ + private static final String DEMO_MAIL = "hans@schalter.de"; + + /** Field description */ + private static final String DEMO_PASSWORD = "hans123"; + + /** Field description */ + private static final String DEMO_USERNAME = "hans"; + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * @param username + * @param password + * + * @return + */ + @Override + public User authenticate(HttpServletRequest request, String username, + String password) + { + User user = null; + + if (DEMO_USERNAME.equals(username) && DEMO_PASSWORD.equals(password)) + { + user = new User(username, DEMO_DISPLAYNAME, DEMO_MAIL); + + HttpSession session = request.getSession(true); + + session.setAttribute(DemoAuthenticator.class.getName(), user); + } + + return user; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param request + * + * @return + */ + @Override + public User getUser(HttpServletRequest request) + { + User user = null; + HttpSession session = request.getSession(); + + if (session != null) + { + user = (User) session.getAttribute(DemoAuthenticator.class.getName()); + } + + return user; + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/SecurityFilter.java b/scm-webapp/src/main/java/sonia/scm/security/SecurityFilter.java similarity index 50% rename from scm-webapp/src/main/java/sonia/scm/api/rest/SecurityFilter.java rename to scm-webapp/src/main/java/sonia/scm/security/SecurityFilter.java index e15ecf0959..75b418daee 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/SecurityFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/security/SecurityFilter.java @@ -5,12 +5,20 @@ -package sonia.scm.api.rest; +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.User; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.security.Principal; + +import javax.inject.Inject; + import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -19,6 +27,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; /** @@ -68,15 +77,23 @@ public class SecurityFilter implements Filter String uri = request.getRequestURI().substring(request.getContextPath().length()); - if (uri.startsWith(URL_AUTHENTICATION) - || (request.getSession(true).getAttribute("auth") != null)) + if (!uri.startsWith(URL_AUTHENTICATION)) { - chain.doFilter(req, res); + User user = authenticator.getUser(request); + + if (user != null) + { + ((HttpServletResponse) res).sendError( + HttpServletResponse.SC_UNAUTHORIZED); + } + else + { + chain.doFilter(new ScmHttpServletRequest(request, user), res); + } } else { - ((HttpServletResponse) res).sendError( - HttpServletResponse.SC_UNAUTHORIZED); + chain.doFilter(req, res); } } else @@ -99,4 +116,79 @@ public class SecurityFilter implements Filter // do nothing } + + //~--- inner classes -------------------------------------------------------- + + /** + * Class description + * + * + * @version Enter version here..., 10/09/08 + * @author Enter your name here... + */ + private static class ScmHttpServletRequest extends HttpServletRequestWrapper + { + + /** + * Constructs ... + * + * + * @param request + * @param user + */ + public ScmHttpServletRequest(HttpServletRequest request, User user) + { + super(request); + this.user = user; + } + + //~--- get methods -------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getRemoteUser() + { + return user.getName(); + } + + /** + * Method description + * + * + * @return + */ + public User getUser() + { + return user; + } + + /** + * Method description + * + * + * @return + */ + @Override + public Principal getUserPrincipal() + { + return user; + } + + //~--- fields ------------------------------------------------------------- + + /** Field description */ + private User user; + } + + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @Inject + private Authenticator authenticator; }