/** * 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. */ package org.apache.cxf.rs.security.oauth2.grants.code; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityNotFoundException; import javax.persistence.TypedQuery; import org.apache.cxf.rs.security.oauth2.common.Client; import org.apache.cxf.rs.security.oauth2.common.UserSubject; import org.apache.cxf.rs.security.oauth2.provider.JPAOAuthDataProvider; import org.apache.cxf.rs.security.oauth2.provider.OAuthServiceException; public class JPACodeDataProvider extends JPAOAuthDataProvider implements AuthorizationCodeDataProvider { private long codeLifetime = 10 * 60; @Override public ServerAuthorizationCodeGrant createCodeGrant(AuthorizationCodeRegistration reg) throws OAuthServiceException { ServerAuthorizationCodeGrant grant = doCreateCodeGrant(reg); saveCodeGrant(grant); return grant; } protected ServerAuthorizationCodeGrant doCreateCodeGrant(AuthorizationCodeRegistration reg) throws OAuthServiceException { return AbstractCodeDataProvider.initCodeGrant(reg, codeLifetime); } protected void saveCodeGrant(final ServerAuthorizationCodeGrant grant) { executeInTransaction(new EntityManagerOperation<Void>() { @Override public Void execute(EntityManager em) { if (grant.getSubject() != null) { UserSubject sub = em.find(UserSubject.class, grant.getSubject().getId()); if (sub == null) { em.persist(grant.getSubject()); } else { sub = em.merge(grant.getSubject()); grant.setSubject(sub); } } // ensure we have a managed association // (needed for OpenJPA : InvalidStateException: Encountered unmanaged object) if (grant.getClient() != null) { grant.setClient(em.find(Client.class, grant.getClient().getClientId())); } em.persist(grant); return null; } }); } @Override protected void doRemoveClient(final Client c) { executeInTransaction(new EntityManagerOperation<Void>() { @Override public Void execute(EntityManager em) { removeClientCodeGrants(c, em); Client clientToRemove = em.getReference(Client.class, c.getClientId()); em.remove(clientToRemove); return null; } }); } protected void removeClientCodeGrants(final Client c) { executeInTransaction(new EntityManagerOperation<Void>() { @Override public Void execute(EntityManager em) { removeClientCodeGrants(c, em); return null; } }); } protected void removeClientCodeGrants(final Client c, EntityManager em) { for (ServerAuthorizationCodeGrant grant : getCodeGrants(c, null, em)) { removeCodeGrant(grant.getCode(), em); } } @Override public ServerAuthorizationCodeGrant removeCodeGrant(final String code) throws OAuthServiceException { return executeInTransaction(new EntityManagerOperation<ServerAuthorizationCodeGrant>() { @Override public ServerAuthorizationCodeGrant execute(EntityManager em) { return removeCodeGrant(code, em); } }); } private ServerAuthorizationCodeGrant removeCodeGrant(String code, EntityManager em) throws OAuthServiceException { ServerAuthorizationCodeGrant grant = em.getReference(ServerAuthorizationCodeGrant.class, code); try { em.remove(grant); } catch (EntityNotFoundException e) { } return grant; } @Override public List<ServerAuthorizationCodeGrant> getCodeGrants(final Client c, final UserSubject subject) throws OAuthServiceException { return execute(new EntityManagerOperation<List<ServerAuthorizationCodeGrant>>() { @Override public List<ServerAuthorizationCodeGrant> execute(EntityManager em) { return getCodeGrants(c, subject, em); } }); } private List<ServerAuthorizationCodeGrant> getCodeGrants(final Client c, final UserSubject subject, EntityManager em) throws OAuthServiceException { return getCodesQuery(c, subject, em).getResultList(); } public void setCodeLifetime(long codeLifetime) { this.codeLifetime = codeLifetime; } protected TypedQuery<ServerAuthorizationCodeGrant> getCodesQuery(Client c, UserSubject resourceOwnerSubject, EntityManager em) { if (c == null && resourceOwnerSubject == null) { return em.createQuery("SELECT c FROM ServerAuthorizationCodeGrant c", ServerAuthorizationCodeGrant.class); } else if (c == null) { return em.createQuery( "SELECT c FROM ServerAuthorizationCodeGrant" + " c JOIN c.subject s" + " WHERE s.login = :login", ServerAuthorizationCodeGrant.class) .setParameter("login", resourceOwnerSubject.getLogin()); } else if (resourceOwnerSubject == null) { return em.createQuery( "SELECT code FROM ServerAuthorizationCodeGrant code" + " JOIN code.client c" + " WHERE c.clientId = :clientId", ServerAuthorizationCodeGrant.class) .setParameter("clientId", c.getClientId()); } else { return em.createQuery( "SELECT code FROM ServerAuthorizationCodeGrant code" + " JOIN code.subject s" + " JOIN code.client c" + " WHERE s.login = :login" + " AND c.clientId = :clientId", ServerAuthorizationCodeGrant.class) .setParameter("clientId", c.getClientId()) .setParameter("login", resourceOwnerSubject.getLogin()); } } }