mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-07-13 06:03:28 +02:00
start implementation of authentication and authorization
This commit is contained in:
@@ -32,6 +32,26 @@
|
||||
<version>1.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- logging -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>log4j-over-slf4j</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.freemarker</groupId>
|
||||
@@ -51,12 +71,6 @@
|
||||
<version>${jersey.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>${logback.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>rome</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import org.apache.shiro.authc.SaltedAuthenticationInfo;
|
||||
import org.apache.shiro.codec.Base64;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
import org.apache.shiro.subject.SimplePrincipalCollection;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@XmlRootElement(name = "admin-account")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class AdminAccountConfiguration implements SaltedAuthenticationInfo
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = -8678832281151044462L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public AdminAccountConfiguration() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param username
|
||||
* @param salt
|
||||
* @param password
|
||||
*/
|
||||
public AdminAccountConfiguration(String username, String salt,
|
||||
String password)
|
||||
{
|
||||
this.username = username;
|
||||
this.salt = salt;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final AdminAccountConfiguration other = (AdminAccountConfiguration) obj;
|
||||
|
||||
return Objects.equal(username, other.username)
|
||||
&& Objects.equal(salt, other.salt)
|
||||
&& Objects.equal(password, other.password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(username, salt, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("username", username)
|
||||
.add("salt", "xxx")
|
||||
.add("password", "xxx")
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object getCredentials()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ByteSource getCredentialsSalt()
|
||||
{
|
||||
return ByteSource.Util.bytes(Base64.decode(salt));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public PrincipalCollection getPrincipals()
|
||||
{
|
||||
|
||||
// TODO
|
||||
return new SimplePrincipalCollection(username, "scm-backend");
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getSalt()
|
||||
{
|
||||
return salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String password;
|
||||
|
||||
/** Field description */
|
||||
private String salt;
|
||||
|
||||
/** Field description */
|
||||
private String username;
|
||||
}
|
||||
@@ -42,7 +42,6 @@ import sonia.scm.xml.XmlIntervalAdapter;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
@@ -61,6 +60,17 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
public class BackendConfiguration
|
||||
{
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public AdminAccountConfiguration getAdminAccount()
|
||||
{
|
||||
return adminAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -140,6 +150,10 @@ public class BackendConfiguration
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "admin-account")
|
||||
private AdminAccountConfiguration adminAccount;
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "directory")
|
||||
@XmlElementWrapper(name = "directories")
|
||||
|
||||
@@ -39,10 +39,14 @@ import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.servlet.GuiceServletContextListener;
|
||||
|
||||
import org.apache.shiro.guice.web.ShiroWebModule;
|
||||
|
||||
import sonia.scm.plugin.scanner.PluginScannerScheduler;
|
||||
import sonia.scm.plugin.security.SecurityModule;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
/**
|
||||
@@ -74,6 +78,7 @@ public class BackendContextListener extends GuiceServletContextListener
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent servletContextEvent)
|
||||
{
|
||||
this.servletContext = servletContextEvent.getServletContext();
|
||||
super.contextInitialized(servletContextEvent);
|
||||
scheduler = injector.getInstance(PluginScannerScheduler.class);
|
||||
scheduler.start();
|
||||
@@ -90,7 +95,8 @@ public class BackendContextListener extends GuiceServletContextListener
|
||||
@Override
|
||||
protected Injector getInjector()
|
||||
{
|
||||
injector = Guice.createInjector(new ScmBackendModule());
|
||||
injector = Guice.createInjector(ShiroWebModule.guiceFilterModule(),
|
||||
new SecurityModule(servletContext), new ScmBackendModule());
|
||||
|
||||
return injector;
|
||||
}
|
||||
@@ -102,4 +108,7 @@ public class BackendContextListener extends GuiceServletContextListener
|
||||
|
||||
/** Field description */
|
||||
private PluginScannerScheduler scheduler;
|
||||
|
||||
/** Field description */
|
||||
private ServletContext servletContext;
|
||||
}
|
||||
|
||||
38
scm-plugin-backend/src/main/java/sonia/scm/plugin/Roles.java
Normal file
38
scm-plugin-backend/src/main/java/sonia/scm/plugin/Roles.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
package sonia.scm.plugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class Roles
|
||||
{
|
||||
public static final String ADMIN = "admin";
|
||||
}
|
||||
@@ -36,7 +36,6 @@ package sonia.scm.plugin;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.name.Names;
|
||||
import com.google.inject.servlet.ServletModule;
|
||||
|
||||
import net.sf.ehcache.CacheManager;
|
||||
@@ -51,7 +50,6 @@ import sonia.scm.plugin.scanner.DefaultPluginScannerFactory;
|
||||
import sonia.scm.plugin.scanner.PluginScannerFactory;
|
||||
import sonia.scm.plugin.scanner.PluginScannerScheduler;
|
||||
import sonia.scm.plugin.scanner.TimerPluginScannerScheduler;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.web.proxy.ProxyConfigurationProvider;
|
||||
import sonia.scm.web.proxy.ProxyServlet;
|
||||
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin.rest;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import sonia.scm.plugin.BackendConfiguration;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import com.sun.jersey.api.view.Viewable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Path("admin")
|
||||
public class AdminResource extends ViewableResource
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String PAGE_OVERVIEW = "/admin/index";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* @param configuration
|
||||
*/
|
||||
@Inject
|
||||
public AdminResource(ServletContext context,
|
||||
BackendConfiguration configuration)
|
||||
{
|
||||
super(context, configuration);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("index.html")
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public Viewable overview()
|
||||
{
|
||||
Map<String, Object> env = createVarMap("Administrator");
|
||||
|
||||
return new Viewable(PAGE_OVERVIEW, env);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin.rest;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import sonia.scm.plugin.BackendConfiguration;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import com.sun.jersey.api.view.Viewable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Path("error")
|
||||
public class ErrorResource extends ViewableResource
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String PAGE_UNAUTHORIZED = "/error/Unauthorized.html";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* @param configuration
|
||||
*/
|
||||
@Inject
|
||||
public ErrorResource(ServletContext context,
|
||||
BackendConfiguration configuration)
|
||||
{
|
||||
super(context, configuration);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("unauthorized.html")
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public Viewable unauthorized()
|
||||
{
|
||||
Map<String, Object> env = createVarMap("Unauthorized");
|
||||
|
||||
return new Viewable(PAGE_UNAUTHORIZED, env);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin.rest;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import sonia.scm.plugin.BackendConfiguration;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import com.sun.jersey.api.view.Viewable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Path("/page/login.html")
|
||||
public class LoginResource extends ViewableResource
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String PAGE_LOGIN = "/login";
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* @param configuration
|
||||
*/
|
||||
@Inject
|
||||
public LoginResource(ServletContext context,
|
||||
BackendConfiguration configuration)
|
||||
{
|
||||
super(context, configuration);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@POST
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public Viewable loginFailed()
|
||||
{
|
||||
Map<String, Object> vars = createVarMap("Login");
|
||||
|
||||
vars.put("error", "Login failed");
|
||||
|
||||
return new Viewable(PAGE_LOGIN, vars);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
public Viewable getForm()
|
||||
{
|
||||
Map<String, Object> vars = createVarMap("Login");
|
||||
|
||||
return new Viewable(PAGE_LOGIN, vars);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin.security;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.AuthenticationInfo;
|
||||
import org.apache.shiro.authc.AuthenticationToken;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.authc.UsernamePasswordToken;
|
||||
import org.apache.shiro.authc.credential.CredentialsMatcher;
|
||||
import org.apache.shiro.authz.AuthorizationInfo;
|
||||
import org.apache.shiro.authz.SimpleAuthorizationInfo;
|
||||
import org.apache.shiro.realm.AuthorizingRealm;
|
||||
import org.apache.shiro.subject.PrincipalCollection;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.plugin.AdminAccountConfiguration;
|
||||
import sonia.scm.plugin.BackendConfiguration;
|
||||
import sonia.scm.plugin.Roles;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class DefaultAdminRealm extends AuthorizingRealm
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
public static final String NAME = "scm.backend";
|
||||
|
||||
/**
|
||||
* the logger for ScmBackendRealm
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(DefaultAdminRealm.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param credentialsMatcher
|
||||
*/
|
||||
@Inject
|
||||
public DefaultAdminRealm(BackendConfiguration configuration,
|
||||
CredentialsMatcher credentialsMatcher)
|
||||
{
|
||||
super(credentialsMatcher);
|
||||
this.configuration = configuration;
|
||||
setAuthenticationTokenClass(UsernamePasswordToken.class);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param token
|
||||
*
|
||||
* @return
|
||||
*
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
@Override
|
||||
protected AuthenticationInfo doGetAuthenticationInfo(
|
||||
AuthenticationToken token)
|
||||
throws AuthenticationException
|
||||
{
|
||||
Preconditions.checkNotNull(token);
|
||||
|
||||
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
|
||||
|
||||
String username = upToken.getUsername();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("start authentication for user {}", username);
|
||||
}
|
||||
|
||||
AdminAccountConfiguration adminAccount = configuration.getAdminAccount();
|
||||
|
||||
if (!adminAccount.getUsername().equals(adminAccount.getUsername()))
|
||||
{
|
||||
throw new UnknownAccountException("unknown account ".concat(username));
|
||||
}
|
||||
|
||||
return adminAccount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param principals
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(
|
||||
PrincipalCollection principals)
|
||||
{
|
||||
if (principals == null)
|
||||
{
|
||||
throw new AuthenticationException("principals should not be null");
|
||||
}
|
||||
|
||||
return new SimpleAuthorizationInfo(ImmutableSet.of(Roles.ADMIN));
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private BackendConfiguration configuration;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer. 2. Redistributions in
|
||||
* binary form must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
|
||||
* nor the names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* http://bitbucket.org/sdorra/scm-manager
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
package sonia.scm.plugin.security;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.name.Named;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
import org.apache.shiro.authc.credential.CredentialsMatcher;
|
||||
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
|
||||
import org.apache.shiro.crypto.RandomNumberGenerator;
|
||||
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
|
||||
import org.apache.shiro.crypto.hash.SimpleHash;
|
||||
import org.apache.shiro.guice.web.ShiroWebModule;
|
||||
import org.apache.shiro.util.ByteSource;
|
||||
|
||||
import sonia.scm.plugin.Roles;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class SecurityModule extends ShiroWebModule
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String ATTRIBUTE_FAILURE = "shiroLoginFailure";
|
||||
|
||||
/** Field description */
|
||||
private static final String HASH_ALGORITHM = "SHA-256";
|
||||
|
||||
/** Field description */
|
||||
private static final int HASH_ITERATIONS = 1024;
|
||||
|
||||
/** Field description */
|
||||
private static final String PAGE_LOGIN = "/page/login.html";
|
||||
|
||||
/** Field description */
|
||||
private static final String PAGE_SUCCESS = "/admin/index.html";
|
||||
|
||||
/** Field description */
|
||||
private static final String PAGE_UNAUTHORIZED = "/error/unauthorized.html";
|
||||
|
||||
/** Field description */
|
||||
private static final String PARAM_PASSWORD = "password";
|
||||
|
||||
/** Field description */
|
||||
private static final String PARAM_REMEMBERME = "rememberme";
|
||||
|
||||
/** Field description */
|
||||
private static final String PARAM_USERNAME = "username";
|
||||
|
||||
/** Field description */
|
||||
private static final String PATTERN_ADMIN = "/admin/**";
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_USERNAMEPARAM =
|
||||
Names.named("shiro.usernameParam");
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_UNAUTHORIZEDURL =
|
||||
Names.named("shiro.unauthorizedUrl");
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_SUCCESSURL = Names.named("shiro.successUrl");
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_REMEMBERMEPARAM =
|
||||
Names.named("shiro.rememberMeParam");
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_PASSWORDPARAM =
|
||||
Names.named("shiro.passwordParam");
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_LOGINURL = Names.named("shiro.loginUrl");
|
||||
|
||||
/** Field description */
|
||||
private static final Named NAMED_FAILUREKEYATTRIBUTE =
|
||||
Names.named("shiro.failureKeyAttribute");
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param servletContext
|
||||
*/
|
||||
public SecurityModule(ServletContext servletContext)
|
||||
{
|
||||
super(servletContext);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String value = JOptionPane.showInputDialog("Password");
|
||||
RandomNumberGenerator rng = new SecureRandomNumberGenerator();
|
||||
ByteSource salt = rng.nextBytes();
|
||||
SimpleHash hash = new SimpleHash(HASH_ALGORITHM, value, salt,
|
||||
HASH_ITERATIONS);
|
||||
|
||||
System.out.append("Salt: ").println(salt.toBase64());
|
||||
System.out.append("Hash: ").println(hash.toBase64());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected void configureShiroWeb()
|
||||
{
|
||||
bindConstants();
|
||||
bindCredentialsMatcher();
|
||||
|
||||
// bind realm
|
||||
bindRealm().to(DefaultAdminRealm.class);
|
||||
|
||||
// add filters
|
||||
addFilterChain(PAGE_LOGIN, AUTHC);
|
||||
addFilterChain(PATTERN_ADMIN, AUTHC, config(ROLES, Roles.ADMIN));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
private void bindConstants()
|
||||
{
|
||||
bindConstant().annotatedWith(NAMED_LOGINURL).to(PAGE_LOGIN);
|
||||
bindConstant().annotatedWith(NAMED_USERNAMEPARAM).to(PARAM_USERNAME);
|
||||
bindConstant().annotatedWith(NAMED_PASSWORDPARAM).to(PARAM_PASSWORD);
|
||||
bindConstant().annotatedWith(NAMED_REMEMBERMEPARAM).to(PARAM_REMEMBERME);
|
||||
bindConstant().annotatedWith(NAMED_SUCCESSURL).to(PAGE_SUCCESS);
|
||||
bindConstant().annotatedWith(NAMED_UNAUTHORIZEDURL).to(PAGE_UNAUTHORIZED);
|
||||
bindConstant().annotatedWith(NAMED_FAILUREKEYATTRIBUTE).to(
|
||||
ATTRIBUTE_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
private void bindCredentialsMatcher()
|
||||
{
|
||||
HashedCredentialsMatcher matcher =
|
||||
new HashedCredentialsMatcher(HASH_ALGORITHM);
|
||||
|
||||
matcher.setHashIterations(HASH_ITERATIONS);
|
||||
matcher.setStoredCredentialsHexEncoded(false);
|
||||
bind(CredentialsMatcher.class).toInstance(matcher);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,9 @@
|
||||
|
||||
<logger name="sonia.scm" level="DEBUG" />
|
||||
<logger name="sonia.scm.plugin.scanner.DefaultPluginScanner" level="INFO" />
|
||||
|
||||
<!-- trace logging -->
|
||||
<logger name="org.apache.shiro" level="INFO" />
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="STDOUT" />
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<#include "../template/header.html">
|
||||
|
||||
<h2>Admin</h2>
|
||||
|
||||
<#include "../template/footer.html">
|
||||
@@ -0,0 +1,5 @@
|
||||
<#include "../template/header.html">
|
||||
|
||||
<h2>Unauthorized</h2>
|
||||
|
||||
<#include "../template/footer.html">
|
||||
28
scm-plugin-backend/src/main/webapp/WEB-INF/ftl/login.html
Normal file
28
scm-plugin-backend/src/main/webapp/WEB-INF/ftl/login.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<#include "template/header.html">
|
||||
|
||||
<form method="POST" action="">
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="username">Username</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="username">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="password">Password</label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" name="password">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<input type="submit" value="Login">
|
||||
|
||||
</form>
|
||||
|
||||
<#include "template/footer.html">
|
||||
@@ -113,6 +113,9 @@
|
||||
<header class="entry-header">
|
||||
<h1 class="entry-title">${title}</h1>
|
||||
</header>
|
||||
<#if error??>
|
||||
<div style="color: red">${error}</div>
|
||||
</#if>
|
||||
<div class="entry-content">
|
||||
<!-- content begin -->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user