Add JPA Key Provider
This commit is contained in:
parent
5420374314
commit
13aa63a4e5
|
@ -26,6 +26,7 @@
|
|||
<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>
|
||||
<class>org.apache.archiva.redback.keys.jpa.model.JpaAuthenticationKey</class>
|
||||
<properties>
|
||||
<property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:redback_database"/>
|
||||
<property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<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>
|
||||
<class>org.apache.archiva.redback.keys.jpa.model.JpaAuthenticationKey</class>
|
||||
<properties>
|
||||
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
|
||||
<property name="openjpa.jdbc.SchemaFactory" value="native(ForeignKeys=true)" />
|
||||
|
|
|
@ -31,5 +31,6 @@
|
|||
<module>redback-keys-jdo</module>
|
||||
<module>redback-keys-memory</module>
|
||||
<module>redback-keys-cached</module>
|
||||
<module>redback-keys-jpa</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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-keys-providers</artifactId>
|
||||
<groupId>org.apache.archiva.redback</groupId>
|
||||
<version>2.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>redback-keys-jpa</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Redback :: Key Management Provider :: JPA</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.archiva.redback</groupId>
|
||||
<artifactId>redback-keys-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.archiva.redback</groupId>
|
||||
<artifactId>redback-common-jpa</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-keys-tests</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa</artifactId>
|
||||
<version>${openjpa.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${springVersion}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<version>${springVersion}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa-maven-plugin</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<configuration>
|
||||
<includes>**/model/*.class</includes>
|
||||
<addDefaultConstructor>true</addDefaultConstructor>
|
||||
<enforcePropertyRestrictions>true</enforcePropertyRestrictions>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enhancer</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>enhance</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.openjpa</groupId>
|
||||
<artifactId>openjpa</artifactId>
|
||||
<!-- set the version to be the same as the level in your runtime -->
|
||||
<version>${openjpa.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,156 @@
|
|||
package org.apache.archiva.redback.keys.jpa;
|
||||
|
||||
import org.apache.archiva.redback.keys.AbstractKeyManager;
|
||||
import org.apache.archiva.redback.keys.AuthenticationKey;
|
||||
import org.apache.archiva.redback.keys.KeyManagerException;
|
||||
import org.apache.archiva.redback.keys.KeyNotFoundException;
|
||||
import org.apache.archiva.redback.keys.jpa.model.JpaAuthenticationKey;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Created by martin on 27.10.16.
|
||||
*/
|
||||
@Service( "keyManager#jpa" )
|
||||
public class JpaKeyManager extends AbstractKeyManager {
|
||||
|
||||
@PersistenceContext(unitName = "redback-jpa")
|
||||
EntityManager em;
|
||||
|
||||
// JpaUserManager is a singleton and initialization should be thread safe
|
||||
private AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
public void setEntityManager(EntityManager em) {
|
||||
this.em = em;
|
||||
}
|
||||
|
||||
private EntityManager getEm() {
|
||||
if (initialized.compareAndSet(false,true)) {
|
||||
Query q = em.createQuery("SELECT COUNT(u.key) FROM JpaAuthenticationKey u");
|
||||
boolean dbInit = q.getFirstResult()==0;
|
||||
}
|
||||
return em;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return "JPA Key Manager - " + this.getClass().getName();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public AuthenticationKey createKey( String principal, String purpose, int expirationMinutes )
|
||||
throws KeyManagerException
|
||||
{
|
||||
JpaAuthenticationKey authkey = new JpaAuthenticationKey();
|
||||
authkey.setKey( super.generateUUID() );
|
||||
authkey.setForPrincipal( principal );
|
||||
authkey.setPurpose( purpose );
|
||||
|
||||
Calendar now = getNowGMT();
|
||||
authkey.setDateCreated( now.getTime() );
|
||||
|
||||
if ( expirationMinutes >= 0 )
|
||||
{
|
||||
Calendar expiration = getNowGMT();
|
||||
expiration.add( Calendar.MINUTE, expirationMinutes );
|
||||
authkey.setDateExpires( expiration.getTime() );
|
||||
}
|
||||
|
||||
return addKey( authkey );
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public AuthenticationKey addKey(AuthenticationKey key) {
|
||||
final EntityManager em = getEm();
|
||||
AuthenticationKey mergedKey = em.merge((JpaAuthenticationKey)key);
|
||||
return mergedKey;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void eraseDatabase()
|
||||
{
|
||||
final EntityManager em = getEm();
|
||||
Query q = em.createQuery("DELETE FROM JpaAuthenticationKey k");
|
||||
q.executeUpdate();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public AuthenticationKey findKey(final String key) throws KeyNotFoundException, KeyManagerException {
|
||||
final EntityManager em = getEm();
|
||||
if ( StringUtils.isEmpty( key ) )
|
||||
{
|
||||
throw new KeyNotFoundException( "Empty key not found." );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TypedQuery<JpaAuthenticationKey> q =
|
||||
em.createQuery("SELECT k FROM JpaAuthenticationKey k WHERE k.key = :key",JpaAuthenticationKey.class);
|
||||
q.setParameter("key",key);
|
||||
JpaAuthenticationKey authkey = q.getSingleResult();
|
||||
if ( authkey == null )
|
||||
{
|
||||
throw new KeyNotFoundException( "Key [" + key + "] not found." );
|
||||
}
|
||||
assertNotExpired( authkey );
|
||||
|
||||
return authkey;
|
||||
} catch (NoResultException ex) {
|
||||
throw new KeyNotFoundException("Key [" + key + "] not found.");
|
||||
} catch (KeyNotFoundException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
log.error("Error while trying to retrieve JpaAuthenticationKey {}", key);
|
||||
throw new KeyManagerException("Error while retrieving key "+key+": "+ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
protected void assertNotExpired(AuthenticationKey authkey) throws KeyManagerException {
|
||||
super.assertNotExpired(authkey);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void deleteKey(AuthenticationKey key) throws KeyManagerException {
|
||||
final EntityManager em = getEm();
|
||||
em.remove((JpaAuthenticationKey)key);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public void deleteKey(String key) throws KeyManagerException {
|
||||
try {
|
||||
JpaAuthenticationKey foundKey = (JpaAuthenticationKey)findKey(key);
|
||||
em.remove(foundKey);
|
||||
} catch (KeyNotFoundException ex) {
|
||||
// Ignore
|
||||
} catch (Exception ex) {
|
||||
log.error("Error occured while trying to find key {}: {}", key, ex.getMessage());
|
||||
throw new KeyManagerException("Error while retrieving key "+key, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AuthenticationKey> getAllKeys() {
|
||||
final EntityManager em = getEm();
|
||||
Query q= em.createQuery("SELECT x from JpaAuthenticationKey x");
|
||||
return q.getResultList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package org.apache.archiva.redback.keys.jpa.model;
|
||||
|
||||
import org.apache.archiva.redback.keys.AuthenticationKey;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by martin on 27.10.16.
|
||||
*/
|
||||
@javax.persistence.Entity
|
||||
@Table(name="JDOAUTHENTICATIONKEY")
|
||||
public class JpaAuthenticationKey implements AuthenticationKey {
|
||||
|
||||
@Column(name="AUTHKEY")
|
||||
@Id
|
||||
private String key;
|
||||
|
||||
@Column(name="FOR_PRINCIPAL")
|
||||
private String forPrincipal;
|
||||
|
||||
@Column(name="PURPOSE")
|
||||
private String purpose;
|
||||
|
||||
@Column(name="DATE_CREATED")
|
||||
private Date dateCreated;
|
||||
|
||||
@Column(name="DATE_EXPIRES")
|
||||
private Date dateExpires;
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getForPrincipal() {
|
||||
return forPrincipal;
|
||||
}
|
||||
|
||||
public void setForPrincipal(String forPrincipal) {
|
||||
this.forPrincipal = forPrincipal;
|
||||
}
|
||||
|
||||
public String getPurpose() {
|
||||
return purpose;
|
||||
}
|
||||
|
||||
public void setPurpose(String purpose) {
|
||||
this.purpose = purpose;
|
||||
}
|
||||
|
||||
public Date getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public void setDateCreated(Date dateCreated) {
|
||||
this.dateCreated = dateCreated;
|
||||
}
|
||||
|
||||
public Date getDateExpires() {
|
||||
return dateExpires;
|
||||
}
|
||||
|
||||
public void setDateExpires(Date dateExpires) {
|
||||
this.dateExpires = dateExpires;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
JpaAuthenticationKey that = (JpaAuthenticationKey) o;
|
||||
|
||||
return key.equals(that.key);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return key.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<?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"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<context:annotation-config />
|
||||
<context:component-scan base-package="org.apache.archiva.redback.keys.jpa" />
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,65 @@
|
|||
package org.apache.archiva.redback.keys.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.keys.KeyManager;
|
||||
import org.apache.archiva.redback.keys.KeyManagerTestCase;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
/**
|
||||
* JdoKeyManagerTest
|
||||
*
|
||||
* @author <a href="mailto:martin_s@apache.org">Martin Stockhammer</a>
|
||||
*
|
||||
*/
|
||||
@Transactional
|
||||
public class JpaKeyManagerTest
|
||||
extends KeyManagerTestCase
|
||||
{
|
||||
|
||||
@Inject
|
||||
EntityManagerFactory entityManagerFactory;
|
||||
|
||||
@Inject
|
||||
@Named(value = "keyManager#jpa")
|
||||
KeyManager keyManager;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
throws Exception {
|
||||
|
||||
super.setUp();
|
||||
super.setKeyManager(keyManager);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initialize() {
|
||||
assertNotNull(keyManager);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?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"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
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 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
|
||||
|
||||
<context:component-scan base-package="org.apache.archiva.redback.keys.jpa" />
|
||||
|
||||
|
||||
|
||||
<bean name="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
<property name="jpaVendorAdapter" >
|
||||
<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter" />
|
||||
</property>
|
||||
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence-hsqldb.xml" />
|
||||
<property name="jpaPropertyMap">
|
||||
<map>
|
||||
<entry key="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:redback_database" />
|
||||
<entry key="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver" />
|
||||
<entry key="openjpa.ConnectionUserName" value="sa" />
|
||||
<entry key="openjpa.ConnectionPassword" value="" />
|
||||
<entry key="openjpa.Log" value="DefaultLevel=TRACE, Runtime=TRACE, Tool=INFO, SQL=TRACE" />
|
||||
<entry key="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
|
||||
<entry key="openjpa.jdbc.MappingDefaults"
|
||||
value="ForeignKeyDeleteAction=restrict,JoinForeignKeyDeleteAction=restrict"/>
|
||||
</map>
|
||||
</property>
|
||||
|
||||
</bean>
|
||||
|
||||
<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" >
|
||||
<property name="entityManagerFactory" ref="entityManagerFactory" />
|
||||
</bean>
|
||||
|
||||
<tx:annotation-driven />
|
||||
|
||||
|
||||
</beans>
|
|
@ -23,10 +23,7 @@ import org.springframework.test.context.ContextConfiguration;
|
|||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* KeyManagerTestCase
|
||||
|
@ -115,11 +112,14 @@ public class KeyManagerTestCase
|
|||
assertEquals( "bar", created2.getForPrincipal() );
|
||||
assertEquals( "Something", created2.getPurpose() );
|
||||
|
||||
List<AuthenticationKey> keys = getKeyManager().getAllKeys();
|
||||
System.out.println("foo key "+created1.getKey());
|
||||
System.out.println("bar key "+created2.getKey());
|
||||
List<AuthenticationKey> keys = new ArrayList(getKeyManager().getAllKeys());
|
||||
Collections.sort( keys, new Comparator<AuthenticationKey>()
|
||||
{
|
||||
public int compare( AuthenticationKey key1, AuthenticationKey key2 )
|
||||
{
|
||||
System.out.println("Compare "+key2.getForPrincipal()+key2.getKey()+" - "+key1.getForPrincipal()+key1.getKey());
|
||||
return key2.getForPrincipal().compareTo( key1.getForPrincipal() );
|
||||
}
|
||||
} );
|
||||
|
|
Loading…
Reference in New Issue