separated ticket object from permission object to facilitate re-use of permission object with tokens
parent
f123366069
commit
1be9da52c6
|
@ -17,12 +17,8 @@
|
|||
|
||||
package org.mitre.uma.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.ElementCollection;
|
||||
|
@ -33,38 +29,19 @@ import javax.persistence.GenerationType;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
/**
|
||||
*
|
||||
* An UMA permission, used in the protection API.
|
||||
*
|
||||
* @author jricher
|
||||
*
|
||||
* @author jricher
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "permission")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = Permission.QUERY_TICKET, query = "select p from Permission p where p.ticket = :" + Permission.PARAM_TICKET)
|
||||
})
|
||||
public class Permission {
|
||||
|
||||
public static final String QUERY_TICKET = "Permission.queryByTicket";
|
||||
public static final String PARAM_TICKET = "ticket";
|
||||
|
||||
|
||||
private Long id;
|
||||
private ResourceSet resourceSet;
|
||||
private Set<String> scopes;
|
||||
private String ticket;
|
||||
private Date expiration;
|
||||
private Collection<Claim> claimsSupplied;
|
||||
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
|
@ -74,14 +51,14 @@ public class Permission {
|
|||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the resourceSet
|
||||
*/
|
||||
|
@ -117,55 +94,4 @@ public class Permission {
|
|||
public void setScopes(Set<String> scopes) {
|
||||
this.scopes = scopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ticket
|
||||
*/
|
||||
@Basic
|
||||
@Column(name = "ticket")
|
||||
public String getTicket() {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ticket the ticket to set
|
||||
*/
|
||||
public void setTicket(String ticket) {
|
||||
this.ticket = ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expiration
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "expiration")
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expiration the expiration to set
|
||||
*/
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the claimsSupplied
|
||||
*/
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "permission_id")
|
||||
public Collection<Claim> getClaimsSupplied() {
|
||||
return claimsSupplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param claimsSupplied the claimsSupplied to set
|
||||
*/
|
||||
public void setClaimsSupplied(Collection<Claim> claimsSupplied) {
|
||||
this.claimsSupplied = claimsSupplied;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2015 The MITRE Corporation
|
||||
* and the MIT Kerberos and Internet Trust Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.mitre.uma.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
/**
|
||||
*
|
||||
* An UMA permission, used in the protection API.
|
||||
*
|
||||
* @author jricher
|
||||
*
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "permission_ticket")
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = PermissionTicket.QUERY_TICKET, query = "select p from PermissionTicket p where p.ticket = :" + PermissionTicket.PARAM_TICKET)
|
||||
})
|
||||
public class PermissionTicket {
|
||||
|
||||
public static final String QUERY_TICKET = "PermissionTicket.queryByTicket";
|
||||
public static final String PARAM_TICKET = "ticket";
|
||||
|
||||
private Long id;
|
||||
private Permission permission;
|
||||
private String ticket;
|
||||
private Date expiration;
|
||||
private Collection<Claim> claimsSupplied;
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the permission
|
||||
*/
|
||||
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "permission_id")
|
||||
public Permission getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param permission the permission to set
|
||||
*/
|
||||
public void setPermission(Permission permission) {
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ticket
|
||||
*/
|
||||
@Basic
|
||||
@Column(name = "ticket")
|
||||
public String getTicket() {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ticket the ticket to set
|
||||
*/
|
||||
public void setTicket(String ticket) {
|
||||
this.ticket = ticket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the expiration
|
||||
*/
|
||||
@Basic
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "expiration")
|
||||
public Date getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expiration the expiration to set
|
||||
*/
|
||||
public void setExpiration(Date expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the claimsSupplied
|
||||
*/
|
||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "permission_ticket_id")
|
||||
public Collection<Claim> getClaimsSupplied() {
|
||||
return claimsSupplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param claimsSupplied the claimsSupplied to set
|
||||
*/
|
||||
public void setClaimsSupplied(Collection<Claim> claimsSupplied) {
|
||||
this.claimsSupplied = claimsSupplied;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.mitre.uma.repository;
|
||||
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
|
||||
/**
|
||||
* @author jricher
|
||||
|
@ -26,10 +26,13 @@ import org.mitre.uma.model.Permission;
|
|||
public interface PermissionRepository {
|
||||
|
||||
/**
|
||||
*
|
||||
* Save a permission ticket.
|
||||
*
|
||||
* @param p
|
||||
* @return
|
||||
*/
|
||||
public Permission save(Permission p);
|
||||
public PermissionTicket save(PermissionTicket p);
|
||||
|
||||
/**
|
||||
* Get the permission indicated by its ticket value.
|
||||
|
@ -37,6 +40,6 @@ public interface PermissionRepository {
|
|||
* @param ticket
|
||||
* @return
|
||||
*/
|
||||
public Permission getByTicket(String ticket);
|
||||
public PermissionTicket getByTicket(String ticket);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ package org.mitre.uma.service;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public interface PermissionService {
|
|||
* @return the created (and stored) permission object, with ticket
|
||||
* @throws InsufficientScopeException if the scopes in scopes don't match those in resourceSet.getScopes
|
||||
*/
|
||||
public Permission create(ResourceSet resourceSet, Set<String> scopes);
|
||||
public PermissionTicket createTicket(ResourceSet resourceSet, Set<String> scopes);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -45,6 +45,6 @@ public interface PermissionService {
|
|||
* @param the ticket value to search on
|
||||
* @return the permission object, or null if none is found
|
||||
*/
|
||||
public Permission getByTicket(String ticket);
|
||||
public PermissionTicket getByTicket(String ticket);
|
||||
|
||||
}
|
||||
|
|
|
@ -235,11 +235,16 @@ CREATE TABLE IF NOT EXISTS resource_set_scope (
|
|||
scope VARCHAR(256) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS permission_ticket (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
|
||||
ticket VARCHAR(256) NOT NULL,
|
||||
permission_id BIGINT NOT NULL,
|
||||
expiration TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS permission (
|
||||
id BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) PRIMARY KEY,
|
||||
resource_set_id BIGINT NOT NULL,
|
||||
ticket VARCHAR(256) NOT NULL,
|
||||
expiration TIMESTAMP
|
||||
resource_set_id BIGINT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS permission_scope (
|
||||
|
@ -254,7 +259,7 @@ CREATE TABLE IF NOT EXISTS claim (
|
|||
claim_type VARCHAR(1024),
|
||||
claim_value VARCHAR(1024),
|
||||
resource_set_id BIGINT,
|
||||
permission_id BIGINT
|
||||
permission_ticket_id BIGINT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS claim_token_format (
|
||||
|
|
|
@ -21,7 +21,7 @@ import javax.persistence.EntityManager;
|
|||
import javax.persistence.PersistenceContext;
|
||||
import javax.persistence.TypedQuery;
|
||||
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.repository.PermissionRepository;
|
||||
import org.mitre.util.jpa.JpaUtil;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
@ -39,7 +39,7 @@ public class JpaPermissionRepository implements PermissionRepository {
|
|||
|
||||
@Override
|
||||
@Transactional
|
||||
public Permission save(Permission p) {
|
||||
public PermissionTicket save(PermissionTicket p) {
|
||||
return JpaUtil.saveOrUpdate(p.getId(), em, p);
|
||||
}
|
||||
|
||||
|
@ -47,9 +47,9 @@ public class JpaPermissionRepository implements PermissionRepository {
|
|||
* @see org.mitre.uma.repository.PermissionRepository#getByTicket(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Permission getByTicket(String ticket) {
|
||||
TypedQuery<Permission> query = em.createNamedQuery(Permission.QUERY_TICKET, Permission.class);
|
||||
query.setParameter(Permission.PARAM_TICKET, ticket);
|
||||
public PermissionTicket getByTicket(String ticket) {
|
||||
TypedQuery<PermissionTicket> query = em.createNamedQuery(PermissionTicket.QUERY_TICKET, PermissionTicket.class);
|
||||
query.setParameter(PermissionTicket.PARAM_TICKET, ticket);
|
||||
return JpaUtil.getSingleResult(query.getResultList());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.UUID;
|
|||
|
||||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.repository.PermissionRepository;
|
||||
import org.mitre.uma.service.PermissionService;
|
||||
|
@ -49,7 +50,7 @@ public class DefaultPermissionService implements PermissionService {
|
|||
* @see org.mitre.uma.service.PermissionService#create(org.mitre.uma.model.ResourceSet, java.util.Set)
|
||||
*/
|
||||
@Override
|
||||
public Permission create(ResourceSet resourceSet, Set<String> scopes) {
|
||||
public PermissionTicket createTicket(ResourceSet resourceSet, Set<String> scopes) {
|
||||
|
||||
// check to ensure that the scopes requested are a subset of those in the resource set
|
||||
|
||||
|
@ -57,13 +58,16 @@ public class DefaultPermissionService implements PermissionService {
|
|||
throw new InsufficientScopeException("Scopes of resource set are not enough for requested permission.");
|
||||
}
|
||||
|
||||
Permission p = new Permission();
|
||||
p.setResourceSet(resourceSet);
|
||||
p.setScopes(scopes);
|
||||
p.setTicket(UUID.randomUUID().toString());
|
||||
p.setExpiration(new Date(System.currentTimeMillis() + permissionExpirationSeconds * 1000L));
|
||||
Permission perm = new Permission();
|
||||
perm.setResourceSet(resourceSet);
|
||||
perm.setScopes(scopes);
|
||||
|
||||
return repository.save(p);
|
||||
PermissionTicket ticket = new PermissionTicket();
|
||||
ticket.setPermission(perm);
|
||||
ticket.setTicket(UUID.randomUUID().toString());
|
||||
ticket.setExpiration(new Date(System.currentTimeMillis() + permissionExpirationSeconds * 1000L));
|
||||
|
||||
return repository.save(ticket);
|
||||
|
||||
}
|
||||
|
||||
|
@ -71,7 +75,7 @@ public class DefaultPermissionService implements PermissionService {
|
|||
* @see org.mitre.uma.service.PermissionService#getByTicket(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Permission getByTicket(String ticket) {
|
||||
public PermissionTicket getByTicket(String ticket) {
|
||||
return repository.getByTicket(ticket);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.mitre.openid.connect.view.HttpCodeView;
|
|||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.mitre.uma.model.Claim;
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.service.PermissionService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -102,15 +102,15 @@ public class AuthorizationRequestEndpoint {
|
|||
|
||||
String ticketValue = o.get(TICKET).getAsString();
|
||||
|
||||
Permission perm = permissionService.getByTicket(ticketValue);
|
||||
PermissionTicket ticket = permissionService.getByTicket(ticketValue);
|
||||
|
||||
if (perm != null) {
|
||||
if (ticket != null) {
|
||||
// found the ticket, see if it's any good
|
||||
|
||||
ResourceSet rs = perm.getResourceSet();
|
||||
ResourceSet rs = ticket.getPermission().getResourceSet();
|
||||
Collection<Claim> claimsRequired = rs.getClaimsRequired();
|
||||
|
||||
Collection<Claim> claimsSupplied = perm.getClaimsSupplied();
|
||||
Collection<Claim> claimsSupplied = ticket.getClaimsSupplied();
|
||||
|
||||
Collection<Claim> claimsUnmatched = new HashSet<>(claimsRequired);
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import org.mitre.oauth2.model.SystemScope;
|
|||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.mitre.openid.connect.view.JsonEntityView;
|
||||
import org.mitre.openid.connect.view.JsonErrorView;
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.service.PermissionService;
|
||||
import org.mitre.uma.service.ResourceSetService;
|
||||
|
@ -126,7 +126,7 @@ public class PermissionRegistrationEndpoint {
|
|||
}
|
||||
|
||||
// create the permission
|
||||
Permission permission = permissionService.create(resourceSet, scopes);
|
||||
PermissionTicket permission = permissionService.createTicket(resourceSet, scopes);
|
||||
|
||||
if (permission != null) {
|
||||
// we've created the permission, return the ticket
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mitre.oauth2.service.SystemScopeService;
|
||||
import org.mitre.uma.model.Permission;
|
||||
import org.mitre.uma.model.PermissionTicket;
|
||||
import org.mitre.uma.model.ResourceSet;
|
||||
import org.mitre.uma.repository.PermissionRepository;
|
||||
import org.mockito.AdditionalAnswers;
|
||||
|
@ -94,7 +94,7 @@ public class TestDefaultPermissionService {
|
|||
rs2.setScopes(scopes2);
|
||||
|
||||
// have the repository just pass the argument through
|
||||
when(permissionRepository.save(Mockito.any(Permission.class))).then(AdditionalAnswers.returnsFirstArg());
|
||||
when(permissionRepository.save(Mockito.any(PermissionTicket.class))).then(AdditionalAnswers.returnsFirstArg());
|
||||
|
||||
when(scopeService.scopesMatch(anySetOf(String.class), anySetOf(String.class))).then(new Answer<Boolean>() {
|
||||
|
||||
|
@ -114,12 +114,12 @@ public class TestDefaultPermissionService {
|
|||
|
||||
|
||||
/**
|
||||
* Test method for {@link org.mitre.uma.service.impl.DefaultPermissionService#create(org.mitre.uma.model.ResourceSet, java.util.Set)}.
|
||||
* Test method for {@link org.mitre.uma.service.impl.DefaultPermissionService#createTicket(org.mitre.uma.model.ResourceSet, java.util.Set)}.
|
||||
*/
|
||||
@Test
|
||||
public void testCreate_ticket() {
|
||||
|
||||
Permission perm = permissionService.create(rs1, scopes1);
|
||||
PermissionTicket perm = permissionService.createTicket(rs1, scopes1);
|
||||
|
||||
// we want there to be a non-null ticket
|
||||
assertNotNull(perm.getTicket());
|
||||
|
@ -127,7 +127,7 @@ public class TestDefaultPermissionService {
|
|||
|
||||
@Test
|
||||
public void testCreate_uuid() {
|
||||
Permission perm = permissionService.create(rs1, scopes1);
|
||||
PermissionTicket perm = permissionService.createTicket(rs1, scopes1);
|
||||
|
||||
// we expect this to be a UUID
|
||||
UUID uuid = UUID.fromString(perm.getTicket());
|
||||
|
@ -139,8 +139,8 @@ public class TestDefaultPermissionService {
|
|||
@Test
|
||||
public void testCreate_differentTicketsSameClient() {
|
||||
|
||||
Permission perm1 = permissionService.create(rs1, scopes1);
|
||||
Permission perm2 = permissionService.create(rs1, scopes1);
|
||||
PermissionTicket perm1 = permissionService.createTicket(rs1, scopes1);
|
||||
PermissionTicket perm2 = permissionService.createTicket(rs1, scopes1);
|
||||
|
||||
assertNotNull(perm1.getTicket());
|
||||
assertNotNull(perm2.getTicket());
|
||||
|
@ -153,8 +153,8 @@ public class TestDefaultPermissionService {
|
|||
@Test
|
||||
public void testCreate_differentTicketsDifferentClient() {
|
||||
|
||||
Permission perm1 = permissionService.create(rs1, scopes1);
|
||||
Permission perm2 = permissionService.create(rs2, scopes2);
|
||||
PermissionTicket perm1 = permissionService.createTicket(rs1, scopes1);
|
||||
PermissionTicket perm2 = permissionService.createTicket(rs2, scopes2);
|
||||
|
||||
assertNotNull(perm1.getTicket());
|
||||
assertNotNull(perm2.getTicket());
|
||||
|
@ -168,7 +168,7 @@ public class TestDefaultPermissionService {
|
|||
public void testCreate_scopeMismatch() {
|
||||
@SuppressWarnings("unused")
|
||||
// try to get scopes outside of what we're allowed to do, this should throw an exception
|
||||
Permission perm = permissionService.create(rs1, scopes2);
|
||||
PermissionTicket perm = permissionService.createTicket(rs1, scopes2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue