package com.microsoft.aad.taskapplication.helpers;
import com.microsoft.aad.adal.CacheKey;
import com.microsoft.aad.adal.ITokenCacheStore;
import com.microsoft.aad.adal.ITokenStoreQuery;
import com.microsoft.aad.adal.TokenCacheItem;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
public class InMemoryCacheStore implements ITokenCacheStore, ITokenStoreQuery {
private static final long serialVersionUID = 1L;
private static final String TAG = "InMemoryCacheStore";
private static Object sLock = new Object();
HashMap<String, TokenCacheItem> cache = new HashMap<>();
private static final InMemoryCacheStore INSTANCE = new InMemoryCacheStore();
private InMemoryCacheStore() {}
public static InMemoryCacheStore getInstance() {
return INSTANCE;
}
@Override
public TokenCacheItem getItem(String key) {
if (key == null) {
throw new IllegalArgumentException("key");
}
return cache.get(key);
}
@Override
public void removeItem(String key) {
if (key == null) {
throw new IllegalArgumentException("key");
}
cache.remove(key);
}
@Override
public void setItem(String key, TokenCacheItem item) {
if (key == null) {
throw new IllegalArgumentException("key");
}
if (item == null) {
throw new IllegalArgumentException("item");
}
cache.put(key, item);
}
@Override
public void removeAll() {
cache = new HashMap<>();
}
// Extra helper methods can be implemented here for queries
/**
* User can query over iterator values.
*/
@Override
public Iterator<TokenCacheItem> getAll() {
Iterator<TokenCacheItem> values = cache.values().iterator();
return values;
}
/**
* Unique users with tokens.
*
* @return unique users
*/
@Override
public HashSet<String> getUniqueUsersWithTokenCache() {
Iterator<TokenCacheItem> results = this.getAll();
HashSet<String> users = new HashSet<String>();
while (results.hasNext()) {
TokenCacheItem item = results.next();
if (item.getUserInfo() != null && !users.contains(item.getUserInfo().getUserId())) {
users.add(item.getUserInfo().getUserId());
}
}
return users;
}
/**
* Tokens for resource.
*
* @param resource Resource identifier
* @return list of {@link TokenCacheItem}
*/
@Override
public ArrayList<TokenCacheItem> getTokensForResource(String resource) {
Iterator<TokenCacheItem> results = this.getAll();
ArrayList<TokenCacheItem> tokenItems = new ArrayList<TokenCacheItem>();
while (results.hasNext()) {
TokenCacheItem item = results.next();
if (item.getResource().equals(resource)) {
tokenItems.add(item);
}
}
return tokenItems;
}
/**
* Get tokens for user.
*
* @param userid Userid
* @return list of {@link TokenCacheItem}
*/
@Override
public ArrayList<TokenCacheItem> getTokensForUser(String userid) {
Iterator<TokenCacheItem> results = this.getAll();
ArrayList<TokenCacheItem> tokenItems = new ArrayList<TokenCacheItem>();
while (results.hasNext()) {
TokenCacheItem item = results.next();
if (item.getUserInfo() != null
&& item.getUserInfo().getUserId().equalsIgnoreCase(userid)) {
tokenItems.add(item);
}
}
return tokenItems;
}
/**
* Clear tokens for user without additional retry.
*
* @param userid UserId
*/
@Override
public void clearTokensForUser(String userid) {
ArrayList<TokenCacheItem> results = this.getTokensForUser(userid);
for (TokenCacheItem item : results) {
if (item.getUserInfo() != null
&& item.getUserInfo().getUserId().equalsIgnoreCase(userid)) {
this.removeItem(CacheKey.createCacheKey(item));
}
}
}
/**
* Get tokens about to expire.
*
* @return list of {@link TokenCacheItem}
*/
@Override
public ArrayList<TokenCacheItem> getTokensAboutToExpire() {
Iterator<TokenCacheItem> results = this.getAll();
ArrayList<TokenCacheItem> tokenItems = new ArrayList<TokenCacheItem>();
while (results.hasNext()) {
TokenCacheItem item = results.next();
if (isAboutToExpire(item.getExpiresOn())) {
tokenItems.add(item);
}
}
return tokenItems;
}
private boolean isAboutToExpire(Date expires) {
Date validity = getTokenValidityTime().getTime();
if (expires != null && expires.before(validity)) {
return true;
}
return false;
}
private static final int TOKEN_VALIDITY_WINDOW = 10;
private static Calendar getTokenValidityTime() {
Calendar timeAhead = Calendar.getInstance();
timeAhead.add(Calendar.SECOND, TOKEN_VALIDITY_WINDOW);
return timeAhead;
}
@Override
public boolean contains(String key) {
if (key == null) {
throw new IllegalArgumentException("key");
}
return cache.containsKey(key);
}
}