Adding JPA implementation of users and rbac provider Uses OpenJPA
Project: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/repo Commit: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/commit/62efc70b Tree: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/tree/62efc70b Diff: http://git-wip-us.apache.org/repos/asf/archiva-redback-core/diff/62efc70b Branch: refs/heads/jpa Commit: 62efc70bd27c0ddb8bd01c0f67b0c96646aaaea5 Parents: d17c6ff Author: Martin Stockhammer <marti...@apache.org> Authored: Tue Sep 27 23:13:03 2016 +0200 Committer: Martin Stockhammer <marti...@apache.org> Committed: Tue Sep 27 23:13:03 2016 +0200 ---------------------------------------------------------------------- pom.xml | 14 +- redback-common/pom.xml | 1 + redback-common/redback-common-jpa/pom.xml | 57 +++ .../resources/META-INF/persistence-hsqldb.xml | 41 ++ .../src/main/resources/META-INF/persistence.xml | 36 ++ redback-rbac/redback-rbac-providers/pom.xml | 1 + .../redback-rbac-jpa/pom.xml | 70 +++ .../redback/rbac/jpa/JpaRbacManager.java | 452 +++++++++++++++++++ .../redback/rbac/jpa/model/JpaOperation.java | 91 ++++ .../redback/rbac/jpa/model/JpaPermission.java | 123 +++++ .../redback/rbac/jpa/model/JpaResource.java | 91 ++++ .../archiva/redback/rbac/jpa/model/JpaRole.java | 172 +++++++ .../rbac/jpa/model/JpaUserAssignment.java | 97 ++++ .../redback/rbac/jpa/JpaRbacManagerTest.java | 132 ++++++ .../src/test/resources/spring-context.xml | 40 ++ .../src/test/resources/test.properties | 22 + redback-users/redback-users-providers/pom.xml | 1 + .../redback-users-jpa/pom.xml | 68 +++ .../redback/users/jpa/JpaUserManager.java | 307 +++++++++++++ .../archiva/redback/users/jpa/JpaUserQuery.java | 123 +++++ .../redback/users/jpa/model/JpaUser.java | 206 +++++++++ .../redback/users/jpa/JpaUserManagerTest.java | 86 ++++ .../src/test/resources/spring-context.xml | 50 ++ .../src/test/resources/test.properties | 22 + .../test/AbstractUserManagerTestCase.java | 2 + 25 files changed, 2304 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index fa30ae5..3e218ee 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,8 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <gpg.useagent>true</gpg.useagent> <cxf.version>3.0.3</cxf.version> + <openjpa.version>2.4.1</openjpa.version> + <!-- <redbackTestJdbcUrl>jdbc:derby:memory:users-test;create=true</redbackTestJdbcUrl> <redbackTestJdbcDriver>org.apache.derby.jdbc.EmbeddedDriver</redbackTestJdbcDriver> @@ -300,6 +302,16 @@ <version>${project.version}</version> </dependency> <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-common-jpa</artifactId> + <version>2.5-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-users-jpa</artifactId> + <version>2.5-SNAPSHOT</version> + </dependency> + <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> @@ -930,7 +942,7 @@ <descriptorRefs> <descriptorRef>${sourceReleaseAssemblyDescriptor}</descriptorRef> </descriptorRefs> - <tarLongFileFormat>gnu</tarLongFileFormat> + <tarLongFileMode>gnu</tarLongFileMode> </configuration> </execution> </executions> http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-common/pom.xml ---------------------------------------------------------------------- diff --git a/redback-common/pom.xml b/redback-common/pom.xml index 4a68200..9819bb0 100644 --- a/redback-common/pom.xml +++ b/redback-common/pom.xml @@ -31,5 +31,6 @@ <module>redback-common-jdo</module> <module>redback-common-ldap</module> <module>redback-common-test-resources</module> + <module>redback-common-jpa</module> </modules> </project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-common/redback-common-jpa/pom.xml ---------------------------------------------------------------------- diff --git a/redback-common/redback-common-jpa/pom.xml b/redback-common/redback-common-jpa/pom.xml new file mode 100644 index 0000000..ca3b942 --- /dev/null +++ b/redback-common/redback-common-jpa/pom.xml @@ -0,0 +1,57 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>redback-common</artifactId> + <groupId>org.apache.archiva.redback</groupId> + <version>2.5-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>redback-common-jpa</artifactId> + <packaging>jar</packaging> + <name>Redback :: JPA Common Package</name> + + <dependencies> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-rbac-model</artifactId> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-users-api</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa</artifactId> + <version>${openjpa.version}</version> + </dependency> + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence-hsqldb.xml ---------------------------------------------------------------------- diff --git a/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence-hsqldb.xml b/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence-hsqldb.xml new file mode 100644 index 0000000..a78444e --- /dev/null +++ b/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence-hsqldb.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you 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. + --> +<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> + <persistence-unit name="redback-jpa"> + <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> + <jta-data-source>java:comp/env/jdbc/redbackjpa</jta-data-source> + <class>org.apache.archiva.redback.users.jpa.model.JpaUser</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaOperation</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaResource</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaPermission</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaRole</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaUserAssignment</class> + <properties> + <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:redback_database"/> + <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/> + <property name="openjpa.ConnectionUserName" value="sa"/> + <property name="openjpa.ConnectionPassword" value=""/> + <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/> + <property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" /> + <property name="openjpa.jdbc.MappingDefaults" + value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict"/> + </properties> + </persistence-unit> +</persistence> http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence.xml ---------------------------------------------------------------------- diff --git a/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence.xml b/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000..46878e8 --- /dev/null +++ b/redback-common/redback-common-jpa/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you 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. + --> +<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> + <persistence-unit name="redback-jpa"> + <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> + <jta-data-source>java:comp/env/jdbc/redbackjpa</jta-data-source> + <class>org.apache.archiva.redback.users.jpa.model.JpaUser</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaOperation</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaResource</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaPermission</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaRole</class> + <class>org.apache.archiva.redback.rbac.jpa.model.JpaUserAssignment</class> + <properties> + <property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" /> + <property name="openjpa.jdbc.MappingDefaults" + value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict"/> + </properties> + </persistence-unit> +</persistence> http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/pom.xml ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/pom.xml b/redback-rbac/redback-rbac-providers/pom.xml index 0edb497..a94d451 100644 --- a/redback-rbac/redback-rbac-providers/pom.xml +++ b/redback-rbac/redback-rbac-providers/pom.xml @@ -32,5 +32,6 @@ <module>redback-rbac-memory</module> <module>redback-rbac-cached</module> <module>redback-rbac-ldap</module> + <module>redback-rbac-jpa</module> </modules> </project> http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/pom.xml ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/pom.xml b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/pom.xml new file mode 100644 index 0000000..77045ab --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/pom.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>redback-rbac-providers</artifactId> + <groupId>org.apache.archiva.redback</groupId> + <version>2.5-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>redback-rbac-jpa</artifactId> + <packaging>jar</packaging> + <name>Redback :: RBAC Provider :: JPA</name> + + <dependencies> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-rbac-model</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context-support</artifactId> + </dependency> + <dependency> + <groupId>javax.annotation</groupId> + <artifactId>jsr250-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-rbac-tests</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-common-jpa</artifactId> + </dependency> + + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa</artifactId> + <version>${openjpa.version}</version> + </dependency> + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java new file mode 100644 index 0000000..ced9104 --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManager.java @@ -0,0 +1,452 @@ +package org.apache.archiva.redback.rbac.jpa; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.rbac.*; +import org.apache.archiva.redback.rbac.jpa.model.*; +import org.apache.openjpa.persistence.Type; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.persistence.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Created by martin on 20.09.16. + */ +@Service("rbacManager#jpa") +public class JpaRbacManager extends AbstractRBACManager { + + + @PersistenceContext(unitName = "redback-jpa") + EntityManager em; + + + private AtomicBoolean initialized = new AtomicBoolean(false); + + + public void setEntityManager(EntityManager em) { + this.em = em; + } + + + + @Override + public Role createRole(String name) { + JpaRole role = new JpaRole(); + role.setName(name); + return role; + } + + @Override + public Role saveRole(Role role) throws RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid( role ); + final EntityManager em = getEm(); + em.getTransaction().begin(); + em.persist(role); + + em.getTransaction().commit(); + fireRbacRoleSaved(role); + for (Permission perm : role.getPermissions()) { + fireRbacPermissionSaved(perm); + } + return role; + } + + @Override + public void saveRoles(Collection<Role> roles) throws RbacObjectInvalidException, RbacManagerException { + if ( roles == null ) + { + // Nothing to do. + return; + } + + final EntityManager em = getEm(); + em.getTransaction().begin(); + for (Role role : roles ) { + RBACObjectAssertions.assertValid(role); + em.persist(role); + } + em.getTransaction().commit(); + for (Role role : roles) { + fireRbacRoleSaved(role); + } + } + + @Override + public Role getRole(String roleName) throws RbacObjectNotFoundException, RbacManagerException { + final EntityManager em = getEm(); + TypedQuery<JpaRole> q = em.createQuery("SELECT r FROM JpaRole r WHERE r.name = :rolename", JpaRole.class); + q.setParameter("rolename",roleName); + return q.getSingleResult(); + } + + @Override + public List<Role> getAllRoles() throws RbacManagerException { + final EntityManager em = getEm(); + Query q = em.createQuery("SELECT r FROM JpaRole r"); + return q.getResultList(); + } + + @Override + public void removeRole(Role role) throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(role); + if (!(role instanceof JpaRole)) { + throw new RbacObjectInvalidException("Role object is not instance of JpaRole"); + } + if ( role.isPermanent() ) + { + throw new RbacPermanentException( "Unable to delete permanent role [" + role.getName() + "]" ); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + JpaRole myRole = em.find(JpaRole.class, role.getName()); + if (myRole == null) { + throw new RbacObjectNotFoundException("Role not found "+role.getName()); + } + myRole.setPermissions(new ArrayList<Permission>()); + em.remove(myRole); + em.getTransaction().commit(); + fireRbacRoleRemoved(myRole); + } + + @Override + public Permission createPermission(String name) throws RbacManagerException { + JpaPermission permission = new JpaPermission(); + permission.setName(name); + return permission; + } + + @Override + public Permission createPermission(String name, String operationName, String resourceIdentifier) throws RbacManagerException { + JpaPermission permission = new JpaPermission(); + permission.setName(name); + Operation op; + try { + op = getOperation(operationName); + } catch (RbacObjectNotFoundException ex) { + op = createOperation(operationName); + } + permission.setOperation(op); + Resource res; + try { + res = getResource(resourceIdentifier); + } catch (RbacObjectNotFoundException ex) { + res = createResource(resourceIdentifier); + } + permission.setResource(res); + return permission; + } + + @Override + public Permission savePermission(Permission permission) throws RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(permission); + if (!(permission instanceof JpaPermission)) { + throw new RbacObjectInvalidException("The permission object ist not instance of JpaPermission"); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + em.persist(permission); + em.getTransaction().commit(); + fireRbacPermissionSaved(permission); + return permission; + } + + @Override + public Permission getPermission(String permissionName) throws RbacObjectNotFoundException, RbacManagerException { + final EntityManager em = getEm(); + TypedQuery<Permission> q = em.createQuery("SELECT p FROM JpaPermission p WHERE p.name=:name", Permission.class); + q.setParameter("name",permissionName); + Permission res = q.getSingleResult(); + if (res==null) { + throw new RbacObjectNotFoundException("Permission "+permissionName+" not found"); + } + return res; + } + + @Override + public List<Permission> getAllPermissions() throws RbacManagerException { + final EntityManager em = getEm(); + TypedQuery<JpaPermission> q = em.createQuery("SELECT p FROM JpaPermission p",JpaPermission.class); + return (List<Permission>)(List<?>)q.getResultList(); + } + + @Override + public void removePermission(Permission permission) throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(permission); + if (!(permission instanceof JpaPermission)) { + throw new RbacObjectInvalidException("The permission object is not JpaPermission object"); + } + if ( permission.isPermanent() ) + { + throw new RbacPermanentException( "Unable to delete permanent permission [" + permission.getName() + "]" ); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + Permission p = em.find(JpaPermission.class, permission.getName()); + if (p == null) { + throw new RbacObjectNotFoundException("Permission " + permission.getName() + " not found"); + } + em.remove(p); + em.getTransaction().commit(); + fireRbacPermissionRemoved(p); + } + + @Override + public Operation createOperation(String name) throws RbacManagerException { + JpaOperation op = new JpaOperation(); + op.setName(name); + return op; + } + + @Override + public Operation saveOperation(Operation operation) throws RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(operation); + if (!(operation instanceof JpaOperation)) { + throw new RbacObjectInvalidException("Operation is not JpaOperation object"); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + em.persist(operation); + em.getTransaction().commit(); + return operation; + } + + @Override + public Operation getOperation(String operationName) throws RbacObjectNotFoundException, RbacManagerException { + final EntityManager em = getEm(); + Operation op = em.find(JpaOperation.class,operationName); + if(op==null) { + throw new RbacObjectNotFoundException("Operation "+operationName+" not found"); + } + return op; + } + + @Override + public List<Operation> getAllOperations() throws RbacManagerException { + final EntityManager em = getEm(); + Query q = em.createQuery("SELECT o FROM JpaOperation o"); + return q.getResultList(); + } + + @Override + public void removeOperation(Operation operation) throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(operation); + if (!(operation instanceof JpaOperation)) { + throw new RbacObjectInvalidException("Operation is not JpaOperation object"); + } + if ( operation.isPermanent() ) + { + throw new RbacPermanentException( "Unable to delete permanent operation [" + operation.getName() + "]" ); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + Operation op = em.find(JpaOperation.class, operation.getName()); + if (op==null) { + throw new RbacObjectNotFoundException("Operation not found "+operation.getName()); + } + em.remove(op); + em.getTransaction().commit(); + + } + + @Override + public Resource createResource(String identifier) throws RbacManagerException { + JpaResource resource = new JpaResource(); + resource.setIdentifier(identifier); + return resource; + } + + @Override + public Resource saveResource(Resource resource) throws RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(resource); + if (!(resource instanceof JpaResource)) { + throw new RbacObjectInvalidException("Resource is not JpaResource"); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + em.persist(resource); + em.getTransaction().commit(); + return resource; + } + + @Override + public Resource getResource(String resourceIdentifier) throws RbacObjectNotFoundException, RbacManagerException { + final EntityManager em = getEm(); + Resource r = em.find(JpaResource.class,resourceIdentifier); + if (r==null) { + throw new RbacObjectNotFoundException("Resource "+resourceIdentifier+" not found"); + } + return r; + } + + @Override + public List<Resource> getAllResources() throws RbacManagerException { + final EntityManager em = getEm(); + TypedQuery<JpaResource> q = em.createQuery("SELECT r FROM JpaResource r",JpaResource.class); + return (List<Resource>)(List<?>)q.getResultList(); + } + + @Override + public void removeResource(Resource resource) throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(resource); + if (!(resource instanceof JpaResource)) { + throw new RbacObjectInvalidException("Resource is not JpaResource"); + } + if (resource.isPermanent()) { + throw new RbacObjectInvalidException("Unable to delete permanent resource ["+resource.getIdentifier()+ "]"); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + Resource res = em.find(JpaResource.class, resource.getIdentifier()); + if (res==null) { + throw new RbacObjectNotFoundException("Resource "+resource.getIdentifier()+" not found"); + } + em.remove(res); + em.getTransaction().commit(); + } + + @Override + public UserAssignment createUserAssignment(String principal) throws RbacManagerException { + JpaUserAssignment ua = new JpaUserAssignment(); + ua.setPrincipal(principal); + return ua; + } + + @Override + public UserAssignment saveUserAssignment(UserAssignment userAssignment) throws RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(userAssignment); + if (!(userAssignment instanceof JpaUserAssignment)) { + throw new RbacObjectInvalidException("Cannto save object that is not JpaUserAssignment"); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + em.persist(userAssignment); + em.getTransaction().commit(); + fireRbacUserAssignmentSaved(userAssignment); + return userAssignment; + } + + @Override + public UserAssignment getUserAssignment(String principal) throws RbacObjectNotFoundException, RbacManagerException { + final EntityManager em = getEm(); + UserAssignment ua = em.find(JpaUserAssignment.class, principal); + if (ua==null) { + throw new RbacObjectNotFoundException("User assignment not found "+principal); + } + return ua; + } + + @Override + public List<UserAssignment> getAllUserAssignments() throws RbacManagerException { + final EntityManager em = getEm(); + Query q = em.createQuery("SELECT ua FROM JpaUserAssignment ua"); + return q.getResultList(); + } + + @Override + public List<UserAssignment> getUserAssignmentsForRoles(Collection<String> roleNames) throws RbacManagerException { + final EntityManager em = getEm(); + Query q = em.createQuery("SELECT ua FROM JpaUserAssignment ua, ua.roleNames rn WHERE rn IN :rolenames"); + q.setParameter("rolenames",roleNames); + return q.getResultList(); + } + + @Override + public void removeUserAssignment(UserAssignment userAssignment) throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException { + RBACObjectAssertions.assertValid(userAssignment); + if (userAssignment.isPermanent()) { + throw new RbacObjectInvalidException("Cannot remove permanent object "+userAssignment.getPrincipal()); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + UserAssignment ua = em.find(UserAssignment.class, userAssignment.getPrincipal()); + if (ua==null) { + throw new RbacObjectNotFoundException("User assignment not found "+userAssignment.getPrincipal()); + } + em.remove(ua); + em.getTransaction().commit(); + fireRbacUserAssignmentRemoved(userAssignment); + } + + @Override + public void eraseDatabase() { + final EntityManager em = getEm(); + // Deletion is a bit tricky, because the JPA bulk delete queries do not cascade + // or keep foreign keys into account. + em.getTransaction().begin(); + TypedQuery<JpaPermission> tqp = em.createQuery("SELECT r FROM JpaPermission r",JpaPermission.class); + for(JpaPermission p : tqp.getResultList()) { + p.setOperation(null); + p.setResource(null); + } + TypedQuery<JpaRole> tqr = em.createQuery("SELECT r FROM JpaRole r",JpaRole.class); + for (JpaRole r : tqr.getResultList()) { + r.getPermissions().clear(); + } + em.flush(); + TypedQuery<JpaOperation> tqo = em.createQuery("SELECT o FROM JpaOperation o",JpaOperation.class); + for(JpaOperation o : tqo.getResultList()) { + em.remove(o); + } + TypedQuery<JpaResource> tqre = em.createQuery("SELECT re FROM JpaResource re",JpaResource.class); + for(JpaResource re : tqre.getResultList()) { + em.remove(re); + } + for (JpaPermission p : tqp.getResultList()) { + em.remove(p); + } + for (JpaRole r : tqr.getResultList()) { + em.remove(r); + } + TypedQuery<JpaUserAssignment> tqu = em.createQuery("SELECT ua FROM JpaUserAssignment ua", JpaUserAssignment.class); + for(JpaUserAssignment ua : tqu.getResultList()) { + em.remove(ua); + } + em.getTransaction().commit(); + + + } + + @Override + public String getDescriptionKey() { + return "archiva.redback.rbacmanager.jpa"; + } + + @Override + public boolean isReadOnly() { + return false; + } + + private EntityManager getEm() { + if (initialized.compareAndSet(false, true)) { + Query q = em.createQuery("SELECT COUNT(r.name) FROM JpaRole r"); + boolean dbInit = q.getFirstResult()==0; + fireRbacInit(dbInit); + } + return em; + } + + +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaOperation.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaOperation.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaOperation.java new file mode 100644 index 0000000..66a41a1 --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaOperation.java @@ -0,0 +1,91 @@ +package org.apache.archiva.redback.rbac.jpa.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.rbac.Operation; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + +/** + * Created by martin on 25.09.16. + */ +@Entity +@Table(name="SECURITY_OPERATIONS") +public class JpaOperation implements Operation, Serializable { + + @Id + @Column(name="NAME") + private String name; + @Column(name="DESCRIPTION") + private String description; + @Column(name="PERMANENT") + private boolean permanent; + + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public void setDescription(String description) { + this.description = description; + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JpaOperation that = (JpaOperation) o; + + return name.equals(that.name); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaPermission.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaPermission.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaPermission.java new file mode 100644 index 0000000..4ac6989 --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaPermission.java @@ -0,0 +1,123 @@ +package org.apache.archiva.redback.rbac.jpa.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.rbac.Operation; +import org.apache.archiva.redback.rbac.Permission; +import org.apache.archiva.redback.rbac.Resource; +import org.apache.archiva.redback.rbac.jpa.JpaRbacManager; + +import javax.persistence.*; +import java.io.Serializable; + +/** + * Created by martin on 25.09.16. + */ +@Entity +@Table(name="SECURITY_PERMISSIONS") +public class JpaPermission implements Permission,Serializable { + + @Id + @Column(name="NAME") + private String name; + @Column(name="DESCRIPTION") + private String description; + @Column(name="PERMANENT") + private boolean permanent; + @ManyToOne(cascade = CascadeType.PERSIST) + @JoinColumn( + name="OPERATION_NAME_OID", + referencedColumnName = "NAME" + ) + private JpaOperation operation; + @ManyToOne(cascade = CascadeType.PERSIST) + @JoinColumn( + name="RESOURCE_IDENTIFIER_OID", + referencedColumnName = "IDENTIFIER" + ) + private JpaResource resource; + + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public void setDescription(String description) { + this.description = description; + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + @Override + public Operation getOperation() { + return operation; + } + + @Override + public void setOperation(Operation operation) { + this.operation = (JpaOperation)operation; + } + + @Override + public Resource getResource() { + return resource; + } + + @Override + public void setResource(Resource resource) { + this.resource = (JpaResource)resource; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JpaPermission that = (JpaPermission) o; + + return name.equals(that.name); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaResource.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaResource.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaResource.java new file mode 100644 index 0000000..fc7ee77 --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaResource.java @@ -0,0 +1,91 @@ +package org.apache.archiva.redback.rbac.jpa.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.rbac.Resource; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.io.Serializable; + +/** + * Created by martin on 25.09.16. + */ +@Entity +@Table(name="SECURITY_RESOURCES") +public class JpaResource implements Resource, Serializable { + + @Id + @Column(name="IDENTIFIER") + private String identifier; + @Column(name="PATTERN") + private boolean pattern; + @Column(name="PERMANENT") + private boolean permanent; + + + @Override + public String getIdentifier() { + return identifier; + } + + @Override + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + @Override + public boolean isPattern() { + return pattern; + } + + @Override + public void setPattern(boolean pattern) { + this.pattern = pattern; + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JpaResource that = (JpaResource) o; + + return identifier.equals(that.identifier); + + } + + @Override + public int hashCode() { + return identifier.hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java new file mode 100644 index 0000000..1f8a62c --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaRole.java @@ -0,0 +1,172 @@ +package org.apache.archiva.redback.rbac.jpa.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.rbac.AbstractRole; +import org.apache.archiva.redback.rbac.Permission; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by martin on 25.09.16. + */ +@Entity +@Table( + name="SECURITY_ROLES" +) +public class JpaRole extends AbstractRole implements Serializable { + + @Id + @Column(name="NAME") + private String name; + @Column(name="DESCRIPTION") + private String description; + @Column(name="ASSIGNABLE") + private boolean assignable; + @Column(name="PERMANENT") + private boolean permanent; + @ManyToMany(cascade = CascadeType.PERSIST) + @JoinTable( + name="SECURITY_ROLE_PERMISSION_MAP", + joinColumns={ @JoinColumn(name="NAME_OID", referencedColumnName="NAME") }, + inverseJoinColumns = { + @JoinColumn(name="NAME_EID",referencedColumnName = "NAME") + } + ) + List<JpaPermission> permissions = new ArrayList<JpaPermission>(); + + @ElementCollection + @CollectionTable( + name="SECURITY_ROLE_CHILDROLE_MAP", + joinColumns = { + @JoinColumn(name="NAME_OID",referencedColumnName = "NAME") + } + ) + List<String> childRoleNames = new ArrayList<String>(); + + + + @Override + public void addPermission(Permission permission) { + if (permission instanceof JpaPermission) { + this.permissions.add((JpaPermission) permission); + } + + } + + @Override + public void addChildRoleName(String name) { + this.childRoleNames.add(name); + } + + @Override + public List<String> getChildRoleNames() { + return childRoleNames; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public String getName() { + return name; + } + + @Override + public List<Permission> getPermissions() { + // Maybe better to create a new list? + return (List<Permission>)(List<?>)permissions; + } + + @Override + public boolean isAssignable() { + return assignable; + } + + @Override + public void removePermission(Permission permission) { + this.permissions.remove(permission); + } + + @Override + public void setAssignable(boolean assignable) { + this.assignable=assignable; + } + + @Override + public void setChildRoleNames(List<String> names) { + this.childRoleNames.clear(); + this.childRoleNames.addAll(names); + } + + @Override + public void setDescription(String description) { + this.description=description; + + } + + @Override + public void setName(String name) { + this.name=name; + + } + + @Override + public void setPermissions(List<Permission> permissions) { + this.permissions.clear(); + for (Permission p : permissions) { + if (p instanceof JpaPermission) { + permissions.add(p); + } + } + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public void setPermanent(boolean permanent) { + this.permanent=permanent; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + + JpaRole jpaRole = (JpaRole) o; + + return name.equals(jpaRole.name); + + } + + @Override + public int hashCode() { + return name.hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaUserAssignment.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaUserAssignment.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaUserAssignment.java new file mode 100644 index 0000000..39e0b2d --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/main/java/org/apache/archiva/redback/rbac/jpa/model/JpaUserAssignment.java @@ -0,0 +1,97 @@ +package org.apache.archiva.redback.rbac.jpa.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.rbac.AbstractUserAssignment; + +import javax.persistence.*; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Martin Stockhammer <marti...@apache.org> on 26.09.16. + */ +@Entity +@Table(name="SECURITY_USER_ASSIGNMENTS") +public class JpaUserAssignment extends AbstractUserAssignment implements Serializable { + + + @Id + @Column(name="PRINCIPAL") + private String principal; + @ElementCollection + @Column(name="STRING_ELE") + @CollectionTable( + name="SECURITY_USERASSIGNMENT_MAP", + joinColumns = { + @JoinColumn(name = "PRINCIPAL_OID", referencedColumnName = "PRINCIPAL") + } + ) + private List<String> roleNames = new ArrayList<String>(); + @Column(name="PERMANENT") + private boolean permanent = false; + + @Override + public String getPrincipal() { + return principal; + } + + @Override + public void setPrincipal(String principal) { + this.principal = principal; + } + + @Override + public List<String> getRoleNames() { + return roleNames; + } + + @Override + public void setRoleNames(List<String> roleNames) { + this.roleNames = roleNames; + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + JpaUserAssignment that = (JpaUserAssignment) o; + + return principal.equals(that.principal); + + } + + @Override + public int hashCode() { + return principal.hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManagerTest.java ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManagerTest.java b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManagerTest.java new file mode 100644 index 0000000..3c5bc9f --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/java/org/apache/archiva/redback/rbac/jpa/JpaRbacManagerTest.java @@ -0,0 +1,132 @@ +package org.apache.archiva.redback.rbac.jpa; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.common.jdo.test.StoreManagerDebug; +import org.apache.archiva.redback.rbac.RbacManagerException; +import org.apache.archiva.redback.tests.AbstractRbacManagerTestCase; +import org.junit.Before; +import org.springframework.test.annotation.DirtiesContext; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import java.io.InputStream; +import java.util.Properties; + +/** + * JdoRbacManagerTest: + * + * @author Jesse McConnell + * @author <a href="mailto:joa...@erdfelt.com">Joakim Erdfelt</a> + */ +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class JpaRbacManagerTest + extends AbstractRbacManagerTestCase +{ + + @Inject + @Named(value = "rbacManager#jpa") + JpaRbacManager rbacManager; + + public static int EVENTCOUNT = 2; + + @Override + public void assertEventCount() + { + assertEquals( EVENTCOUNT, eventTracker.initCount ); + } + + /** + * Creates a new RbacStore which contains no data. + */ + @Before + public void setUp() + throws Exception + { + + super.setUp(); + Properties props = new Properties(); + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("test.properties"); + assert is!=null; + props.load(is); + is.close(); + EntityManagerFactory emf = Persistence.createEntityManagerFactory("redback-jpa",props); + + log.info("test setup"); + rbacManager.setEntityManager(emf.createEntityManager()); + super.setRbacManager(rbacManager); + assertNotNull(rbacManager); + log.info("injected rbac manager "+rbacManager); + + } + + + @Override + public void testGetAssignedRoles() + throws RbacManagerException + { + super.testGetAssignedRoles(); + } + + @Override + public void testGetAssignedPermissionsDeep() + throws RbacManagerException + { + super.testGetAssignedPermissionsDeep(); + } + + @Override + protected void afterSetup() + { + super.afterSetup(); + } + + @Override + public void testLargeApplicationInit() + throws RbacManagerException + { + this.clearCache(); + super.testLargeApplicationInit(); + } + + @Override + public void testGetRolesDeep() + throws RbacManagerException + { + this.clearCache(); + super.testGetRolesDeep(); + } + + + @Override + public void testStoreInitialization() + throws Exception + { + this.clearCache(); + rbacManager.eraseDatabase(); + eventTracker.rbacInit( true ); + super.testStoreInitialization(); + assertEquals( EVENTCOUNT, eventTracker.initCount ); + } + + +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/spring-context.xml ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/spring-context.xml b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/spring-context.xml new file mode 100644 index 0000000..abee0b5 --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/spring-context.xml @@ -0,0 +1,40 @@ +<?xml version="1.0"?> + +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you 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. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + + <context:component-scan base-package="org.apache.archiva.redback.rbac.jpa" /> + + <bean name="userConfiguration#default" class="org.apache.archiva.redback.configuration.DefaultUserConfiguration"> + <property name="registry" ref="test-conf"/> + </bean> + + <bean name="commons-configuration" class="org.apache.archiva.redback.components.registry.commons.CommonsConfigurationRegistry"> + </bean> + + <alias name="commons-configuration" alias="test-conf"/> + +</beans> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/test.properties ---------------------------------------------------------------------- diff --git a/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/test.properties b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/test.properties new file mode 100644 index 0000000..df848c4 --- /dev/null +++ b/redback-rbac/redback-rbac-providers/redback-rbac-jpa/src/test/resources/test.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +openjpa.ConnectionURL=jdbc:hsqldb:mem:reback-jpa +openjpa.ConnectionDriverName=org.hsqldb.jdbcDriver +openjpa.ConnectionUserName=sa +openjpa.ConnectionPassword= +openjp.Log=DefaultLevel=WARN,Tool=INFO +openjpa.jdbc.SynchronizeMappings=buildSchema(ForeignKeys=true) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-users/redback-users-providers/pom.xml ---------------------------------------------------------------------- diff --git a/redback-users/redback-users-providers/pom.xml b/redback-users/redback-users-providers/pom.xml index 9ddab02..4a90648 100644 --- a/redback-users/redback-users-providers/pom.xml +++ b/redback-users/redback-users-providers/pom.xml @@ -39,5 +39,6 @@ <module>redback-users-jdo</module> <module>redback-users-ldap</module> <module>redback-users-configurable</module> + <module>redback-users-jpa</module> </modules> </project> http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-users/redback-users-providers/redback-users-jpa/pom.xml ---------------------------------------------------------------------- diff --git a/redback-users/redback-users-providers/redback-users-jpa/pom.xml b/redback-users/redback-users-providers/redback-users-jpa/pom.xml new file mode 100644 index 0000000..2606b71 --- /dev/null +++ b/redback-users/redback-users-providers/redback-users-jpa/pom.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you 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. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>redback-users-providers</artifactId> + <groupId>org.apache.archiva.redback</groupId> + <version>2.5-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>redback-users-jpa</artifactId> + <packaging>jar</packaging> + <name>Redback :: Users Provider :: JPA</name> + + <dependencies> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context-support</artifactId> + </dependency> + <dependency> + <groupId>javax.annotation</groupId> + <artifactId>jsr250-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-policy</artifactId> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-common-jpa</artifactId> + </dependency> + <dependency> + <groupId>org.apache.openjpa</groupId> + <artifactId>openjpa</artifactId> + <version>${openjpa.version}</version> + </dependency> + + <dependency> + <groupId>org.hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.archiva.redback</groupId> + <artifactId>redback-users-tests</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserManager.java ---------------------------------------------------------------------- diff --git a/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserManager.java b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserManager.java new file mode 100644 index 0000000..c4c83f6 --- /dev/null +++ b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserManager.java @@ -0,0 +1,307 @@ +package org.apache.archiva.redback.users.jpa; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.policy.UserSecurityPolicy; +import org.apache.archiva.redback.users.*; +import org.apache.archiva.redback.users.jpa.model.JpaUser; +import org.apache.commons.lang.StringUtils; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.persistence.*; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Created by martin on 20.09.16. + */ +@org.springframework.stereotype.Service("userManager#jpa") +public class JpaUserManager extends AbstractUserManager { + + + @PersistenceContext(unitName = "redback-jpa") + EntityManager em; + + @Inject + private UserSecurityPolicy userSecurityPolicy; + + // JpaUserManager is a singleton and initialization should be thread safe + private AtomicBoolean initialized = new AtomicBoolean(false); + + + public void setEntityManager(EntityManager em) { + this.em = em; + } + + @Override + public boolean isReadOnly() { + return false; + } + + @Override + public String getId() { + return "jpa"; + } + + private EntityManager getEm() { + if (initialized.compareAndSet(false,true)) { + Query q = em.createQuery("SELECT COUNT(u.username) FROM JpaUser u"); + boolean dbInit = q.getFirstResult()==0; + fireUserManagerInit(dbInit); + } + return em; + } + + + @Override + public User createUser(String username, String fullName, String emailAddress) throws UserManagerException { + + JpaUser user = new JpaUser(); + user.setUsername(username); + user.setFullName(fullName); + user.setEmail(emailAddress); + return user; + } + + @Override + public UserQuery createUserQuery() { + return new JpaUserQuery(); + } + + @Override + public List<User> getUsers() throws UserManagerException { + final EntityManager em = getEm(); + Query q= em.createQuery("SELECT x from JpaUser x"); + return q.getResultList(); + } + + @Override + public List<User> getUsers(boolean orderAscending) throws UserManagerException { + final EntityManager em = getEm(); + final String orderFlag = orderAscending ? "ASC" : "DESC"; + Query q = em.createQuery("SELECT u FROM JpaUser u ORDER BY u.username "+orderFlag); + return q.getResultList(); + } + + @Override + public User addUser(User user) throws UserManagerException { + EntityManager em = getEm(); + if ( !( user instanceof JpaUser ) ) + { + throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() + + " is not an instance of " + JpaUser.class.getName() ); + } + + if ( StringUtils.isEmpty( user.getUsername() ) ) + { + throw new IllegalStateException( + Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$ + } + + userSecurityPolicy.extensionChangePassword( user ); + + fireUserManagerUserAdded( user ); + + // TODO: find a better solution + // workaround for avoiding the admin from providing another password on the next login after the + // admin account has been created + // extensionChangePassword by default sets the password change status to false + if ( "admin".equals( user.getUsername() ) ) + { + user.setPasswordChangeRequired( false ); + } + else + { + user.setPasswordChangeRequired( true ); + } + em.getTransaction().begin(); + em.persist((JpaUser)user); + em.getTransaction().commit(); + return user; + } + + @Override + public User updateUser(User user) throws UserNotFoundException, UserManagerException { + return updateUser(user, false); + } + + @Override + public User findUser(String username) throws UserNotFoundException, UserManagerException { + if (username==null) { + throw new UserNotFoundException("Username was <null>"); + } + final EntityManager em = getEm(); + TypedQuery<JpaUser> q = em.createQuery("SELECT u FROM JpaUser u WHERE LOWER(u.username)=:uname", JpaUser.class); + q.setParameter("uname",username.toLowerCase()); + User result; + try { + result = q.getSingleResult(); + } catch (NoResultException ex ) { + throw new UserNotFoundException(ex); + } + return result; + } + + @Override + public User findUser(String username, boolean useCache) throws UserNotFoundException, UserManagerException { + return findUser(username); + } + + @Override + public List<User> findUsersByUsernameKey(String usernameKey, boolean orderAscending) throws UserManagerException { + return findUsers("username",usernameKey,"username",orderAscending); + } + + @Override + public List<User> findUsersByFullNameKey(String fullNameKey, boolean orderAscending) throws UserManagerException { + return findUsers("fullName",fullNameKey,"username",orderAscending); + } + + @Override + public List<User> findUsersByEmailKey(String emailKey, boolean orderAscending) throws UserManagerException { + return findUsers("email",emailKey,"username", orderAscending); + } + + @Override + public List<User> findUsersByQuery(final UserQuery queryParam) throws UserManagerException { + final EntityManager em = getEm(); + final JpaUserQuery query = (JpaUserQuery)queryParam; + String orderByAttribute = ""; + if (UserQuery.ORDER_BY_EMAIL.equals(query.getOrderBy())) { + orderByAttribute="email"; + } else if (UserQuery.ORDER_BY_FULLNAME.equals(query.getOrderBy())) { + orderByAttribute="fullName"; + } else if (UserQuery.ORDER_BY_USERNAME.equals(query.getOrderBy())) { + orderByAttribute="username"; + } else { + throw new IllegalArgumentException("Unknown order attribute "+query.getOrderBy()); + } + StringBuilder sb = new StringBuilder("SELECT u FROM JpaUser u "); + if (query.hasUsername()||query.hasFullName()||query.hasEmail()) { + sb.append("WHERE "); + } + boolean checkBefore = false; + if (query.hasUsername()) { + sb.append("LOWER(u.username) LIKE :username "); + checkBefore=true; + } + if (query.hasEmail()) { + if (checkBefore) { + sb.append("AND "); + } + checkBefore=true; + sb.append("LOWER(u.email) LIKE :email "); + } + if (query.hasFullName()) { + if (checkBefore) { + sb.append("AND "); + } + sb.append("LOWER(u.fullName) LIKE :fullname "); + } + if (query.getOrderBy()!=null && !"".equals(query.getOrderBy())) { + sb.append("ORDER BY u.").append(orderByAttribute).append(query.isAscending() ? " ASC" : " DESC"); + } + TypedQuery<User> q = em.createQuery(sb.toString(), User.class); + if (query.hasUsername()) { + q.setParameter("username", "%"+query.getUsername().toLowerCase()+"%"); + } + if (query.hasEmail()) { + q.setParameter("email", "%"+query.getEmail().toLowerCase()+"%"); + } + if (query.hasFullName()) { + q.setParameter("fullname", "%"+query.getFullName().toLowerCase()+"%"); + } + q.setFirstResult((int)query.getFirstResult()).setMaxResults((int)query.getMaxResults()); + return q.getResultList(); + } + + private List<User> findUsers(final String attribute, final String pattern, + final String orderAttribute, final boolean orderAscending) { + final EntityManager em = getEm(); + StringBuilder sb = new StringBuilder("SELECT u FROM JpaUser u WHERE LOWER(u."); + sb.append(attribute).append(") LIKE :patternvalue ORDER BY u.").append(orderAttribute); + sb.append(orderAscending ? " ASC" : " DESC"); + TypedQuery<User> q = em.createQuery(sb.toString(),User.class); + q.setParameter("patternvalue","%"+pattern.toLowerCase()+"%"); + return q.getResultList(); + } + + @Override + public boolean userExists(String principal) throws UserManagerException { + EntityManager em = getEm(); + JpaUser user = em.find(JpaUser.class, principal); + return user != null; + } + + + + @Override + public void deleteUser(String username) throws UserNotFoundException, UserManagerException { + final EntityManager em = getEm(); + User u = findUser(username); + if (u.isPermanent()) { + throw new PermanentUserException("User "+username+" cannot be deleted"); + } + em.getTransaction().begin(); + em.remove(u); + em.getTransaction().commit(); + fireUserManagerUserRemoved(u); + } + + @Override + public void addUserUnchecked(User user) throws UserManagerException { + + } + + @Override + public void eraseDatabase() { + EntityManager em = getEm(); + em.getTransaction().begin(); + Query q = em.createQuery("DELETE FROM JpaUser u"); + q.executeUpdate(); + em.getTransaction().commit(); + } + + @Override + public User updateUser(User user, boolean passwordChangeRequired) throws UserNotFoundException, UserManagerException { + if ( StringUtils.isNotEmpty( user.getPassword() ) ) + { + userSecurityPolicy.extensionChangePassword( user, passwordChangeRequired ); + } + final EntityManager em = getEm(); + em.getTransaction().begin(); + em.persist((JpaUser)user); + em.getTransaction().commit(); + fireUserManagerUserUpdated(user); + return user; + } + + @Override + public String getDescriptionKey() { + return null; + } + + + + +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserQuery.java ---------------------------------------------------------------------- diff --git a/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserQuery.java b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserQuery.java new file mode 100644 index 0000000..d48a59c --- /dev/null +++ b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/JpaUserQuery.java @@ -0,0 +1,123 @@ +package org.apache.archiva.redback.users.jpa; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import org.apache.archiva.redback.users.UserQuery; + +import java.util.Arrays; + +/** + * Created by martin on 23.09.16. + */ +public class JpaUserQuery implements UserQuery { + + private String username; + private String email; + private String fullName; + private long firstResult=0; + private long maxResults=Integer.MAX_VALUE; + private boolean ascending=true; + + private String orderBy="username"; + + @Override + public String getUsername() { + return username; + } + + @Override + public void setUsername(String username) { + this.username = username; + } + + public boolean hasUsername() { + return username != null && !"".equals(username); + } + + @Override + public String getEmail() { + return email; + } + + @Override + public void setEmail(String email) { + this.email = email; + } + + public boolean hasEmail() { + return email!=null && !"".equals(email); + } + + @Override + public String getFullName() { + return fullName; + } + + @Override + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public boolean hasFullName() { + return fullName!=null && !"".equals(fullName); + } + + @Override + public long getFirstResult() { + return firstResult; + } + + public void setFirstResult(int firstResult) { + this.firstResult = firstResult; + } + + @Override + public long getMaxResults() { + return maxResults; + } + + public void setMaxResults(int maxResults) { + this.maxResults = maxResults; + } + + @Override + public boolean isAscending() { + return ascending; + } + + @Override + public void setAscending(boolean ascending) { + this.ascending = ascending; + } + + + @Override + public String getOrderBy() { + return orderBy; + } + + @Override + public void setOrderBy(String orderBy) { + if (!UserQuery.ALLOWED_ORDER_FIELDS.contains(orderBy)) { + throw new IllegalArgumentException("Order attribute not allowed: "+orderBy); + } + this.orderBy = orderBy; + } +} http://git-wip-us.apache.org/repos/asf/archiva-redback-core/blob/62efc70b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/model/JpaUser.java ---------------------------------------------------------------------- diff --git a/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/model/JpaUser.java b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/model/JpaUser.java new file mode 100644 index 0000000..04f441e --- /dev/null +++ b/redback-users/redback-users-providers/redback-users-jpa/src/main/java/org/apache/archiva/redback/users/jpa/model/JpaUser.java @@ -0,0 +1,206 @@ +package org.apache.archiva.redback.users.jpa.model; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Created by martin on 20.09.16. + */ +@Entity +@Table(name="JDOUSER") +public class JpaUser implements org.apache.archiva.redback.users.User { + + @Id + private String username; + + private String fullName; + private String email; + private String encodedPassword; + private Date lastPasswordChange; + @ElementCollection + private List<String> previousEncodedPasswords = new ArrayList<String>(); + private boolean permanent; + private boolean locked; + private boolean passwordChangeRequired; + private boolean validated; + private int countFailedLoginAttempts; + private Date accountCreationDate; + private Date lastLoginDate; + private String rawPassword; + + + @Override + public String getUsername() { + return username; + } + + @Override + public void setUsername(String name) { + this.username = name; + } + + @Override + public String getFullName() { + return fullName; + } + + @Override + public void setFullName(String name) { + this.fullName = name; + } + + @Override + public String getEmail() { + return email; + } + + @Override + public void setEmail(String address) { + this.email = address; + } + + @Override + public String getPassword() { + return rawPassword; + } + + @Override + public void setPassword(String rawPassword) { + this.rawPassword = rawPassword; + } + + @Override + public String getEncodedPassword() { + return encodedPassword; + } + + @Override + public void setEncodedPassword(String encodedPassword) { + this.encodedPassword = encodedPassword; + } + + @Override + public Date getLastPasswordChange() { + return lastPasswordChange; + } + + @Override + public void setLastPasswordChange(Date passwordChangeDate) { + this.lastPasswordChange = lastPasswordChange; + } + + @Override + public List<String> getPreviousEncodedPasswords() { + return previousEncodedPasswords; + } + + @Override + public void setPreviousEncodedPasswords(List<String> encodedPasswordList) { + this.previousEncodedPasswords.clear(); + this.previousEncodedPasswords.addAll(encodedPasswordList); + } + + @Override + public void addPreviousEncodedPassword(String encodedPassword) { + this.previousEncodedPasswords.add(encodedPassword); + } + + @Override + public boolean isPermanent() { + return permanent; + } + + @Override + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + @Override + public boolean isLocked() { + return locked; + } + + @Override + public void setLocked(boolean locked) { + this.locked = locked; + } + + @Override + public boolean isPasswordChangeRequired() { + return passwordChangeRequired; + } + + @Override + public void setPasswordChangeRequired(boolean changeRequired) { + this.passwordChangeRequired = changeRequired; + } + + @Override + public boolean isValidated() { + return validated; + } + + @Override + public void setValidated(boolean valid) { + this.validated = valid; + } + + @Override + public int getCountFailedLoginAttempts() { + return countFailedLoginAttempts; + } + + @Override + public void setCountFailedLoginAttempts(int count) { + this.countFailedLoginAttempts = count; + } + + @Override + public Date getAccountCreationDate() { + return accountCreationDate; + } + + @Override + public void setAccountCreationDate(Date date) { + this.accountCreationDate = date; + } + + @Override + public Date getLastLoginDate() { + return lastLoginDate; + } + + @Override + public void setLastLoginDate(Date date) { + this.lastLoginDate = date; + } + + @Override + public String getUserManagerId() { + return null; + } +}