com.baasbox.security.SessionTokenProvider.java Source code

Java tutorial

Introduction

Here is the source code for com.baasbox.security.SessionTokenProvider.java

Source

/*
 * Copyright (c) 2014.
 *
 * BaasBox - info-at-baasbox.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.baasbox.security;

import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import play.libs.Akka;
import play.mvc.Http;
import scala.concurrent.duration.FiniteDuration;
import akka.actor.Cancellable;

import com.baasbox.service.logging.BaasBoxLogger;
import com.google.common.collect.ImmutableMap;

public class SessionTokenProvider implements ISessionTokenProvider {

    protected class SessionCleaner implements Runnable {
        @Override
        public void run() {
            BaasBoxLogger.info("Session Cleaner: started");
            Enumeration<String> tokens = getTokens();
            long totalTokens = 0;
            long removedTokens = 0;
            while (tokens.hasMoreElements()) {
                totalTokens++;
                if (isExpired(tokens.nextElement()))
                    removedTokens++;
            }
            BaasBoxLogger.info("Session cleaner: tokens: " + totalTokens + " - removed: " + removedTokens);
            BaasBoxLogger.info("Session cleaner: finished");
        }
    }

    protected final static ConcurrentHashMap<String, ImmutableMap<SessionKeys, ? extends Object>> sessions = new ConcurrentHashMap<String, ImmutableMap<SessionKeys, ? extends Object>>();
    protected long expiresInMilliseconds = 0; //default expiration of session tokens
    protected long sessionClenanerLaunchInMinutes = 60; //the session cleaner will be launch each x minutes.

    private Cancellable sessionCleaner = null;
    private static SessionTokenProvider me;

    private static ISessionTokenProvider initialize() {
        if (me == null)
            me = new SessionTokenProvider();
        return me;
    }

    public static ISessionTokenProvider getSessionTokenProvider() {
        return initialize();
    }

    public static void destroySessionTokenProvider() {
        if (me != null && me.sessionCleaner != null) {
            me.sessionCleaner.cancel();
            BaasBoxLogger.info("Session Cleaner: cancelled");
        }
        me = null;
    }

    public SessionTokenProvider() {
        setTimeout(expiresInMilliseconds);
        startSessionCleaner(sessionClenanerLaunchInMinutes * 60000); //converts minutes in milliseconds
    };

    public void setTimeout(long timeoutInMilliseconds) {
        this.expiresInMilliseconds = timeoutInMilliseconds;
        if (BaasBoxLogger.isDebugEnabled())
            BaasBoxLogger.debug("New session timeout: " + timeoutInMilliseconds + " ms");
    } //setTimeout

    @Override
    public ImmutableMap<SessionKeys, ? extends Object> setSession(String AppCode, String username,
            String password) {
        UUID token = UUID.randomUUID();
        ImmutableMap<SessionKeys, ? extends Object> info = ImmutableMap.of(SessionKeys.APP_CODE, AppCode,
                SessionKeys.TOKEN, token.toString(), SessionKeys.USERNAME, username, SessionKeys.PASSWORD, password,
                SessionKeys.EXPIRE_TIME, (new Date()).getTime() + expiresInMilliseconds);
        sessions.put(token.toString(), info);
        return info;
    }

    @Override
    public ImmutableMap<SessionKeys, ? extends Object> getSession(String token) {
        if (isExpired(token)) {
            return null;
        }
        ImmutableMap<SessionKeys, ? extends Object> info = sessions.get(token);
        ImmutableMap<SessionKeys, ? extends Object> newInfo = ImmutableMap.of(SessionKeys.APP_CODE,
                info.get(SessionKeys.APP_CODE), SessionKeys.TOKEN, token, SessionKeys.USERNAME,
                info.get(SessionKeys.USERNAME), SessionKeys.PASSWORD, info.get(SessionKeys.PASSWORD),
                SessionKeys.EXPIRE_TIME, (new Date()).getTime() + expiresInMilliseconds);
        sessions.put(token, newInfo);
        return newInfo;
    }

    @Override
    public void removeSession(String token) {
        if (BaasBoxLogger.isDebugEnabled())
            BaasBoxLogger.debug("SessionTokenProvider: " + token + " removed");
        sessions.remove(token);

    }

    @Override
    public Enumeration<String> getTokens() {
        return sessions.keys();
    }

    private boolean isExpired(String token) {
        ImmutableMap<SessionKeys, ? extends Object> info = sessions.get(token);
        if (info == null)
            return true;
        if (expiresInMilliseconds != 0 && (new Date()).getTime() > (Long) info.get(SessionKeys.EXPIRE_TIME)) {
            removeSession(token);
            return true;
        }
        return false;
    }

    private void startSessionCleaner(long timeoutInMilliseconds) {
        sessionCleaner = Akka.system().scheduler().schedule(new FiniteDuration(1000, TimeUnit.MILLISECONDS),
                new FiniteDuration(timeoutInMilliseconds, TimeUnit.MILLISECONDS), new SessionCleaner(),
                Akka.system().dispatcher());
    }

    @Override
    public List<ImmutableMap<SessionKeys, ? extends Object>> getSessions(String username) {
        Stream<ImmutableMap<SessionKeys, ? extends Object>> values = sessions.values().stream()
                .filter(x -> x.get(SessionKeys.USERNAME).equals(username));
        List<ImmutableMap<SessionKeys, ? extends Object>> toRet = values.collect(Collectors.toList());
        return toRet;
    }

    @Override
    public ImmutableMap<SessionKeys, ? extends Object> getCurrent() {
        String token = (String) Http.Context.current().args.get("token");
        if (token != null)
            return sessions.get(token);
        else
            return null;
    }
}