package org.fluxtream.core.services.impl; import org.fluxtream.core.domain.oauth2.Application; import org.fluxtream.core.domain.oauth2.AuthorizationCode; import org.fluxtream.core.domain.oauth2.AuthorizationCodeResponse; import org.fluxtream.core.domain.oauth2.AuthorizationToken; import org.fluxtream.core.mvc.models.AuthorizationTokenModel; import org.fluxtream.core.services.OAuth2MgmtService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * User: candide * Date: 10/04/14 * Time: 14:04 */ @Service @Transactional(readOnly=true) public class OAuth2MgmtServiceImpl implements OAuth2MgmtService { @PersistenceContext EntityManager em; @Override public Application getApplicationForClientId(final String clientId) { final TypedQuery<Application> query = em.createQuery( "SELECT application FROM Application application " + "WHERE application.uid=?", Application.class); query.setParameter(1, clientId); final List<Application> resultList = query.getResultList(); if (resultList.size()>0) return resultList.get(0); return null; } @Override @Transactional(readOnly=false) public AuthorizationCode issueAuthorizationCode(final Long id, final Set<String> scopes, final String state) { AuthorizationCode code = new AuthorizationCode(id, scopes, state); em.persist(code); return code; } @Override public AuthorizationCode getCode(final String code) { final TypedQuery<AuthorizationCode> query = em.createQuery( "SELECT authorizationCode FROM AuthorizationCode authorizationCode " + "WHERE authorizationCode.code=?", AuthorizationCode.class); query.setParameter(1, code); final List<AuthorizationCode> resultList = query.getResultList(); if (resultList.size()>0) return resultList.get(0); return null; } @Override public AuthorizationCodeResponse getResponse(final String code) { AuthorizationCode authCode = getCode(code); if (authCode==null) return null; final TypedQuery<AuthorizationCodeResponse> query = em.createQuery( "SELECT authorizationCodeResponse FROM AuthorizationCodeResponse authorizationCodeResponse " + "WHERE authorizationCodeResponse.authorizationCodeId=?", AuthorizationCodeResponse.class); query.setParameter(1, authCode.getId()); final List<AuthorizationCodeResponse> resultList = query.getResultList(); if (resultList.size()>0) return resultList.get(0); return null; } @Override @Transactional(readOnly=false) public void storeVerification(final AuthorizationCodeResponse codeResponse) { em.persist(codeResponse); } @Override @Transactional(readOnly=false) public void storeToken(final AuthorizationToken token) { // discard old tokens with the same authorization code final Query query = em.createQuery("DELETE FROM AuthorizationToken token WHERE token.authorizationCodeId=?"); query.setParameter(1, token.authorizationCodeId); query.executeUpdate(); em.persist(token); } @Override @Transactional(readOnly=false) public AuthorizationToken issueAuthorizationToken(long guestId, long applicationId) { AuthorizationCode code = new AuthorizationCode(guestId, null, null); code.applicationId = applicationId; em.persist(code); AuthorizationToken token = new AuthorizationToken(guestId); token.authorizationCodeId = code.getId(); em.persist(token); return token; } @Override public AuthorizationToken getTokenFromRefreshToken(final String refreshToken) { final TypedQuery<AuthorizationToken> query = em.createQuery( "SELECT authorizationToken FROM AuthorizationToken authorizationToken " + "WHERE authorizationToken.refreshToken=?", AuthorizationToken.class); query.setParameter(1, refreshToken); final List<AuthorizationToken> resultList = query.getResultList(); if (resultList.size()>0) return resultList.get(0); return null; } @Override public AuthorizationToken getTokenFromAccessToken(String accessToken) { final TypedQuery<AuthorizationToken> query = em.createQuery( "SELECT authorizationToken FROM AuthorizationToken authorizationToken " + "WHERE authorizationToken.accessToken=?", AuthorizationToken.class); query.setParameter(1, accessToken); final List<AuthorizationToken> resultList = query.getResultList(); if (resultList.size()>0) { final AuthorizationToken authorizationToken = resultList.get(0); return authorizationToken; } return null; } @Override public List<AuthorizationTokenModel> getTokens(long guestId) { final TypedQuery<AuthorizationToken> query = em.createQuery( "SELECT authorizationToken FROM AuthorizationToken authorizationToken " + "WHERE authorizationToken.guestId=?", AuthorizationToken.class); query.setParameter(1, guestId); final List<AuthorizationToken> resultList = query.getResultList(); final List<AuthorizationTokenModel> tokenModels = new ArrayList<AuthorizationTokenModel>(); for (AuthorizationToken authorizationToken : resultList) { AuthorizationCode authCode = em.find(AuthorizationCode.class, authorizationToken.authorizationCodeId); if (authCode==null) continue; Application application = em.find(Application.class, authCode.applicationId); AuthorizationTokenModel tokenModel = new AuthorizationTokenModel(authorizationToken.accessToken, application.name, application.organization, application.website, authCode.creationTime); tokenModels.add(tokenModel); } return tokenModels; } @Override @Transactional(readOnly=false) public void revokeAccessToken(final long guestId, final String accessToken) { final AuthorizationToken authorizationToken = getTokenFromAccessToken(accessToken); if (authorizationToken.guestId!=guestId) throw new RuntimeException("Attempt to revoke an authorizationToken by another user"); // erase the token's associated authorization code response, if there is one Query query = em.createQuery("SELECT response FROM AuthorizationCodeResponse response WHERE authorizationCodeId=?"); query.setParameter(1, authorizationToken.authorizationCodeId); List resultList = query.getResultList(); if (resultList.size()>0) em.remove(resultList.get(0)); // erase the token's associated authorization code, if there is one query = em.createQuery("SELECT code FROM AuthorizationCode code WHERE id=?"); query.setParameter(1, authorizationToken.authorizationCodeId); resultList = query.getResultList(); if (resultList.size()>0) em.remove(resultList.get(0)); query = em.createNativeQuery("DELETE FROM AuthorizationToken WHERE accessToken=?"); query.setParameter(1, accessToken); query.executeUpdate(); } public AuthorizationToken getExistingDeviceToken(final String refreshToken, final long guestId) { final TypedQuery<AuthorizationToken> query = em.createQuery( "SELECT authorizationToken FROM AuthorizationToken authorizationToken " + "WHERE authorizationToken.refreshToken=? AND authorizationToken.guestId=?", AuthorizationToken.class); query.setParameter(1, refreshToken); query.setParameter(2, guestId); final List<AuthorizationToken> resultList = query.getResultList(); if (resultList.size()>0) return resultList.get(0); return null; } @Override @Transactional(readOnly=false) public AuthorizationToken getAuthorizationToken(final long guestId, final String deviceId, final long expirationTime) { if (deviceId==null) throw new RuntimeException("null deviceId when getting an authorizationToken"); final AuthorizationToken existing = getExistingDeviceToken(deviceId, guestId); if (existing!=null && existing.guestId==guestId) { existing.expirationTime = expirationTime; return existing; } AuthorizationToken authorizationToken = new AuthorizationToken(guestId, deviceId, expirationTime); em.persist(authorizationToken); return authorizationToken; } @Override public Application getApplicationForToken(final AuthorizationToken token) { final AuthorizationCode authorizationCode = em.find(AuthorizationCode.class, token.authorizationCodeId); if (authorizationCode!=null) { Application application = em.find(Application.class, authorizationCode.applicationId); return application; } return null; } }