org.cloudfoundry.identity.uaa.login.DefaultAutologinCodeStore.java Source code

Java tutorial

Introduction

Here is the source code for org.cloudfoundry.identity.uaa.login.DefaultAutologinCodeStore.java

Source

/*
 * Cloud Foundry 2012.02.03 Beta
 * Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
 *
 * This product is licensed to you under the Apache License, Version 2.0 (the "License").
 * You may not use this product except in compliance with the License.
 *
 * This product includes a number of subcomponents with
 * separate copyright notices and license terms. Your use of these
 * subcomponents is subject to the terms and conditions of the
 * subcomponent's license, as noted in the LICENSE file.
 */

package org.cloudfoundry.identity.uaa.login;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;

/**
 * @author Dave Syer
 * 
 */
public class DefaultAutologinCodeStore implements AutologinCodeStore {

    private static final Log logger = LogFactory.getLog(DefaultAutologinCodeStore.class);

    private static final long DEFAULT_VALIDITY_PERIOD = 5 * 60 * 1000; // 5 minute

    private Map<String, TokenExpiry> codes = new ConcurrentHashMap<String, TokenExpiry>();

    private final DelayQueue<TokenExpiry> expiryQueue = new DelayQueue<TokenExpiry>();

    private RandomValueStringGenerator generator = new RandomValueStringGenerator(6);

    private long validityPeriod = DEFAULT_VALIDITY_PERIOD;

    private long flushInterval = DEFAULT_VALIDITY_PERIOD * 2;

    private AtomicLong flushTimestamp = new AtomicLong(System.currentTimeMillis());

    private boolean expireCodeWhenUsed = true;

    /**
     * Flag to determine if the authentication codes can be re-used until they expire, or (if true) if they can only be
     * used once.
     * 
     * @param expireCodeWhenUsed the flag to set, default true
     */
    public void setExpireCodeWhenUsed(boolean expireCodeWhenUsed) {
        this.expireCodeWhenUsed = expireCodeWhenUsed;
    }

    @Override
    public Authentication getUser(String code) {
        flush();
        TokenExpiry value = codes.remove(code);
        if (value == null) {
            logger.info("Could not redeem code: " + code);
            return null;
        }
        if (value.getDelay(TimeUnit.MILLISECONDS) <= 0) {
            logger.info("Code expired: " + code);
            expiryQueue.remove(value);
            return null;
        }
        if (expireCodeWhenUsed) {
            expiryQueue.remove(value);
        } else {
            codes.put(code, value);
        }
        logger.info("Redeemed code: " + code);
        return value.getUser();
    }

    @Override
    public String storeUser(Authentication user) {
        flush();
        String code = generator.generate();
        TokenExpiry expiry = new TokenExpiry(code, user, new Date(System.currentTimeMillis() + validityPeriod));
        this.expiryQueue.put(expiry);
        codes.put(code, expiry);
        logger.info("Stored user [" + user.getName() + "] with code: " + code);
        return code;
    }

    private void flush() {
        if (this.flushTimestamp.get() >= System.currentTimeMillis() - this.flushInterval) {
            this.flushTimestamp.set(System.currentTimeMillis());
            TokenExpiry expiry = expiryQueue.poll();
            while (expiry != null) {
                codes.remove(expiry.getValue());
                expiry = expiryQueue.poll();
            }
        }
    }

    private static class TokenExpiry implements Delayed {

        private final long expiry;

        private final String value;

        private final Authentication user;

        public TokenExpiry(String value, Authentication user, Date date) {
            this.value = value;
            this.user = user;
            this.expiry = date.getTime();
        }

        public int compareTo(Delayed other) {
            if (this == other) {
                return 0;
            }
            long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
            return (diff == 0 ? 0 : ((diff < 0) ? -1 : 1));
        }

        public long getDelay(TimeUnit unit) {
            return expiry - System.currentTimeMillis();
        }

        public String getValue() {
            return value;
        }

        public Authentication getUser() {
            return user;
        }

    }
}