package org.openiot.sdum.core.utils;
import org.openiot.commons.util.PropertyManagement;
import org.openiot.security.client.AccessControlUtil;
import org.openiot.security.client.AccessTokenExpiredException;
import org.openiot.security.client.OAuthorizationCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SecurityUtil {
private static Logger logger = LoggerFactory.getLogger(SecurityUtil.class);
private static final int EXPIRY_CHECK_INTERVAL = 5 * 60 * 1000; // some sample value
private static final String SDUM_USERNAME = "security.initialize.sdum.username";
private static final String SDUM_PASSWORD = "security.initialize.sdum.password";
private static String username;
private static String password;
private static AccessControlUtil acUtil = AccessControlUtil.getRestInstance("sdum");
private static long lastExpiryCheck = 0;
private static OAuthorizationCredentials credentials;
static {
PropertyManagement props = new PropertyManagement();
username = props.getProperty(SDUM_USERNAME, "sdumuser");
password = props.getProperty(SDUM_PASSWORD, "sdumuserpass");
}
public static boolean hasPermission(String perm, String accessToken, String clientId) {
return hasPermission(perm, accessToken, clientId, true);
}
/**
* @param perm
* the permission string to be checked
* @param context
* @param accessToken
* the access token of the requester
* @param clientId
* the clientId of the requester
* @param sdumIsTarget
* if true, it is checked if <code>accessToken</code> has the permission
* <code>perm</code> on SDUM. Otherwise, it is checked if <code>accessToken</code>
* has the permission <code>perm</code> on the service specified by the
* <code>clientId.
* @return
*/
public static boolean hasPermission(String perm, String accessToken, String clientId, boolean sdumIsTarget) {
if (credentials == null) {
login();
}
if (credentials != null) {
try {
OAuthorizationCredentials callerCredentials = new OAuthorizationCredentials(accessToken, clientId, null);
OAuthorizationCredentials credentialsToTest = new OAuthorizationCredentials(credentials.getAccessToken(), credentials.getClientId(),
callerCredentials);
boolean hasPermission;
if (sdumIsTarget)
hasPermission = acUtil.hasPermission(perm, credentialsToTest);
else
hasPermission = acUtil.hasPermission(perm, clientId, credentialsToTest);
if (acUtil.getAuthorizationManager().isCachingEnabled()) {
// check if the SDUM access token has expired (this step should be done only if
// caching is enabled)
if (System.currentTimeMillis() - lastExpiryCheck > EXPIRY_CHECK_INTERVAL) {
logger.debug("Checking if SDUM access token is expired");
String expiredAT = acUtil.getExpiredAccessToken(credentialsToTest);
lastExpiryCheck = System.currentTimeMillis();
if (credentials.getAccessToken().equals(expiredAT)) {
// SDUM access token has expired
logger.debug("SDUM access token has expired. Attempting to log in CAS.");
credentials = null;
return hasPermission(perm, accessToken, clientId);
} else if (accessToken.equals(expiredAT)) {
// The access token of the requester is expired
logger.debug("The access token of the requester has expired: {} ", expiredAT);
return false;
}
}
}
return hasPermission;
} catch (AccessTokenExpiredException e) {
if (e.getToken().equals(credentials.getAccessToken())) {
// SDUM access token has expired
logger.debug("SDUM access token has expired. Attempting to log in CAS.");
credentials = null;
return hasPermission(perm, accessToken, clientId, sdumIsTarget);
}
}
}
return false;
}
public static OAuthorizationCredentials getCredentials() {
if (credentials == null)
login();
return credentials;
}
public static synchronized OAuthorizationCredentials login() {
if (credentials != null) {
logger.debug("Credentials found in context. Aborting login process.");
} else {
logger.debug("Logging into CAS by username {}", username);
OAuthorizationCredentials creds = acUtil.login(username, password);
logger.debug("Credentials obtained after logging in is {}", creds);
credentials = creds;
lastExpiryCheck = System.currentTimeMillis();
}
return credentials;
}
}