/*
* oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2014, Gluu
*/
package org.xdi.oxauth.model.common;
import com.unboundid.ldap.sdk.DN;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.RDN;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.xdi.oxauth.model.authorize.JwtAuthorizationRequest;
import org.xdi.oxauth.model.configuration.AppConfiguration;
import org.xdi.oxauth.model.ldap.TokenLdap;
import org.xdi.oxauth.model.registration.Client;
import org.xdi.oxauth.model.util.Util;
import org.xdi.oxauth.service.ClientService;
import org.xdi.oxauth.service.GrantService;
import org.xdi.oxauth.service.UserService;
import org.xdi.service.CacheService;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* Component to hold in memory authorization grant objects.
*
* @author Javier Rojas Blum Date: 09.29.2011
*/
@RequestScoped
public class AuthorizationGrantList implements IAuthorizationGrantList {
@Inject
private Logger log;
@Inject
private Instance<AbstractAuthorizationGrant> grantInstance;
@Inject
private GrantService grantService;
@Inject
private UserService userService;
@Inject
private ClientService clientService;
@Inject
private AppConfiguration appConfiguration;
@Inject
private CacheService cacheService;
@Override
public void removeAuthorizationGrants(List<AuthorizationGrant> authorizationGrants) {
if (authorizationGrants != null && !authorizationGrants.isEmpty()) {
for (AuthorizationGrant r : authorizationGrants) {
grantService.remove(r);
}
}
}
@Override
public AuthorizationGrant createAuthorizationGrant(User user, Client client, Date authenticationTime) {
AuthorizationGrant grant = grantInstance.select(SimpleAuthorizationGrant.class).get();
grant.init(user, null, client, authenticationTime);
return grant;
}
@Override
public AuthorizationCodeGrant createAuthorizationCodeGrant(User user, Client client, Date authenticationTime) {
AuthorizationCodeGrant grant = grantInstance.select(AuthorizationCodeGrant.class).get();
grant.init(user, client, authenticationTime);
MemcachedGrant memcachedGrant = new MemcachedGrant(grant);
cacheService.put(Integer.toString(grant.getAuthorizationCode().getExpiresIn()), memcachedGrant.cacheKey(), memcachedGrant);
log.trace("Put authorization grant in cache, code: " + grant.getAuthorizationCode().getCode() + ", clientId: " + grant.getClientId());
return grant;
}
@Override
public ImplicitGrant createImplicitGrant(User user, Client client, Date authenticationTime) {
ImplicitGrant grant = grantInstance.select(ImplicitGrant.class).get();
grant.init(user, client, authenticationTime);
return grant;
}
@Override
public ClientCredentialsGrant createClientCredentialsGrant(User user, Client client) {
ClientCredentialsGrant grant = grantInstance.select(ClientCredentialsGrant.class).get();
grant.init(user, client);
return grant;
}
@Override
public ResourceOwnerPasswordCredentialsGrant createResourceOwnerPasswordCredentialsGrant(User user, Client client) {
ResourceOwnerPasswordCredentialsGrant grant = grantInstance.select(ResourceOwnerPasswordCredentialsGrant.class).get();
grant.init(user, client);
return grant;
}
@Override
public AuthorizationCodeGrant getAuthorizationCodeGrant(String clientId, String authorizationCode) {
Object cachedGrant = cacheService.get(null, MemcachedGrant.cacheKey(clientId, authorizationCode));
if (cachedGrant == null) {
// retry one time : sometimes during high load cache client may be not fast enough
cachedGrant = cacheService.get(null, MemcachedGrant.cacheKey(clientId, authorizationCode));
log.trace("Failed to fetch authorization grant from cache, code: " + authorizationCode + ", clientId: " + clientId);
}
return cachedGrant instanceof MemcachedGrant ? ((MemcachedGrant) cachedGrant).asCodeGrant(grantInstance) : null;
}
@Override
public AuthorizationGrant getAuthorizationGrantByRefreshToken(String clientId, String refreshTokenCode) {
return load(clientId, refreshTokenCode);
}
@Override
public List<AuthorizationGrant> getAuthorizationGrant(String clientId) {
final List<AuthorizationGrant> result = new ArrayList<AuthorizationGrant>();
try {
final List<TokenLdap> entries = grantService.getGrantsOfClient(clientId);
if (entries != null && !entries.isEmpty()) {
for (TokenLdap t : entries) {
final AuthorizationGrant grant = asGrant(t);
if (grant != null) {
result.add(grant);
}
}
}
} catch (Exception e) {
log.trace(e.getMessage(), e);
}
return result;
}
@Override
public AuthorizationGrant getAuthorizationGrantByAccessToken(String accessToken) {
final TokenLdap tokenLdap = grantService.getGrantsByCode(accessToken);
if (tokenLdap != null && (tokenLdap.getTokenTypeEnum() == org.xdi.oxauth.model.ldap.TokenType.ACCESS_TOKEN || tokenLdap.getTokenTypeEnum() == org.xdi.oxauth.model.ldap.TokenType.LONG_LIVED_ACCESS_TOKEN)) {
return asGrant(tokenLdap);
}
return null;
}
@Override
public AuthorizationGrant getAuthorizationGrantByIdToken(String idToken) {
TokenLdap tokenLdap = grantService.getGrantsByCode(idToken);
if (tokenLdap != null && (tokenLdap.getTokenTypeEnum() == org.xdi.oxauth.model.ldap.TokenType.ID_TOKEN)) {
return asGrant(tokenLdap);
}
return null;
}
public AuthorizationGrant load(String clientId, String p_code) {
return asGrant(grantService.getGrantsByCodeAndClient(p_code, clientId));
}
public String extractClientIdFromTokenDn(String p_dn) {
try {
if (StringUtils.isNotBlank(p_dn)) {
final RDN[] rdNs = DN.getRDNs(p_dn);
if (ArrayUtils.isNotEmpty(rdNs)) {
for (RDN r : rdNs) {
final String[] names = r.getAttributeNames();
if (ArrayUtils.isNotEmpty(names) && Arrays.asList(names).contains("inum")) {
final String[] values = r.getAttributeValues();
if (ArrayUtils.isNotEmpty(values)) {
return values[0];
}
}
}
}
}
} catch (LDAPException e) {
log.trace(e.getMessage(), e);
}
return "";
}
public AuthorizationGrant asGrant(TokenLdap tokenLdap) {
if (tokenLdap != null) {
final AuthorizationGrantType grantType = AuthorizationGrantType.fromString(tokenLdap.getGrantType());
if (grantType != null) {
final User user = userService.getUser(tokenLdap.getUserId());
final Client client = clientService.getClient(extractClientIdFromTokenDn(tokenLdap.getDn()));
final Date authenticationTime = tokenLdap.getAuthenticationTime();
final String nonce = tokenLdap.getNonce();
AuthorizationGrant result;
switch (grantType) {
case AUTHORIZATION_CODE:
AuthorizationCodeGrant authorizationCodeGrant = grantInstance.select(AuthorizationCodeGrant.class).get();
authorizationCodeGrant.init(user, client, authenticationTime);
result = authorizationCodeGrant;
break;
case CLIENT_CREDENTIALS:
ClientCredentialsGrant clientCredentialsGrant = grantInstance.select(ClientCredentialsGrant.class).get();
clientCredentialsGrant.init(user, client);
result = clientCredentialsGrant;
break;
case IMPLICIT:
ImplicitGrant implicitGrant = grantInstance.select(ImplicitGrant.class).get();
implicitGrant.init(user, client, authenticationTime);
result = implicitGrant;
break;
case RESOURCE_OWNER_PASSWORD_CREDENTIALS:
ResourceOwnerPasswordCredentialsGrant resourceOwnerPasswordCredentialsGrant = grantInstance.select(ResourceOwnerPasswordCredentialsGrant.class).get();
resourceOwnerPasswordCredentialsGrant.init(user, client);
result = resourceOwnerPasswordCredentialsGrant;
break;
default:
return null;
}
final String grantId = tokenLdap.getGrantId();
final String jwtRequest = tokenLdap.getJwtRequest();
final String authMode = tokenLdap.getAuthMode();
final String sessionDn = tokenLdap.getSessionDn();
result.setNonce(nonce);
result.setTokenLdap(tokenLdap);
if (StringUtils.isNotBlank(grantId)) {
result.setGrantId(grantId);
}
result.setScopes(Util.splittedStringAsList(tokenLdap.getScope(), " "));
result.setCodeChallenge(tokenLdap.getCodeChallenge());
result.setCodeChallengeMethod(tokenLdap.getCodeChallengeMethod());
if (StringUtils.isNotBlank(jwtRequest)) {
try {
result.setJwtAuthorizationRequest(new JwtAuthorizationRequest(appConfiguration, jwtRequest, client));
} catch (Exception e) {
log.trace(e.getMessage(), e);
}
}
result.setAcrValues(authMode);
result.setSessionDn(sessionDn);
if (tokenLdap.getTokenTypeEnum() != null) {
switch (tokenLdap.getTokenTypeEnum()) {
case AUTHORIZATION_CODE:
if (result instanceof AuthorizationCodeGrant) {
final AuthorizationCode code = new AuthorizationCode(tokenLdap.getTokenCode(), tokenLdap.getCreationDate(), tokenLdap.getExpirationDate());
final AuthorizationCodeGrant g = (AuthorizationCodeGrant) result;
g.setAuthorizationCode(code);
}
break;
case REFRESH_TOKEN:
final RefreshToken refreshToken = new RefreshToken(tokenLdap.getTokenCode(), tokenLdap.getCreationDate(), tokenLdap.getExpirationDate());
result.setRefreshTokens(Arrays.asList(refreshToken));
break;
case ACCESS_TOKEN:
final AccessToken accessToken = new AccessToken(tokenLdap.getTokenCode(), tokenLdap.getCreationDate(), tokenLdap.getExpirationDate());
result.setAccessTokens(Arrays.asList(accessToken));
break;
case ID_TOKEN:
final IdToken idToken = new IdToken(tokenLdap.getTokenCode(), tokenLdap.getCreationDate(), tokenLdap.getExpirationDate());
result.setIdToken(idToken);
break;
case LONG_LIVED_ACCESS_TOKEN:
final AccessToken longLivedAccessToken = new AccessToken(tokenLdap.getTokenCode(), tokenLdap.getCreationDate(), tokenLdap.getExpirationDate());
result.setLongLivedAccessToken(longLivedAccessToken);
break;
}
}
return result;
}
}
return null;
}
}