All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.ocoop.framework.safe.SessionManager Maven / Gradle / Ivy

package cn.ocoop.framework.safe;

import cn.ocoop.framework.safe.auth.service.AuthorizingService;
import cn.ocoop.framework.safe.utils.CookieUtils;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

@Data
public class SessionManager {

    public static SafeProperties safeProperties;
    public static StringRedisTemplate redisTemplate;
    public static AuthorizingService authorizingService;

    public static BoundHashOperations getSession(String sessionId) {
        return redisTemplate.boundHashOps(getSessionkey(sessionId));
    }

    public static BoundHashOperations getSession() {
        return redisTemplate.boundHashOps(getSessionkey(WebContext.get().getSessionId()));
    }

    public static List> getSession(long accountId) {
        Set keys = redisTemplate.keys(getSessionMapKey(accountId, "*"));
        List> sessions = Lists.newArrayList();

        if (CollectionUtils.isNotEmpty(keys)) {
            for (String key : keys) {
                sessions.add(redisTemplate.boundHashOps(key));
            }
        }
        return sessions;
    }

    public static void setAttribute(long accountId, String key, String value) {
        for (BoundHashOperations session : getSession(accountId)) {
            session.put(key, value);
        }
    }

    public static void removeAttribute(long accountId, String key) {
        for (BoundHashOperations session : getSession(accountId)) {
            session.delete(key);
        }
    }


    public static String createSessionId() {
        return UUID.randomUUID().toString();
    }

    public static void setAttribute(String key, String value) {
        getSession().put(key, value);
    }

    public static String getAttribute(String key) {
        return getSession().get(key);
    }

    public static void removeAttribute(String key) {
        getSession().delete(key);
    }

    public static void logout(HttpServletResponse response) {
        getCurrentAccountId().ifPresent(accountId -> {
            redisTemplate.delete(Lists.newArrayList(
                    WebContext.get().getSessionId(),
                    getSessionMapKey(accountId, WebContext.get().getSessionId()),
                    getRoleKey(accountId),
                    getPmsKey(accountId)
            ));

            CookieUtils.clear(response, safeProperties.getSession().getSessionIdCookieName());
        });
    }

    private static BoundHashOperations createSession(HttpServletResponse response, String sessionId, Long accountId) {
        BoundHashOperations hash = redisTemplate.boundHashOps(getSessionkey(sessionId));

        hash.put(SafeProperties.SessionProperties.DEFAULT_SESSION_ID, sessionId);
        hash.expire(2, TimeUnit.DAYS);
        if (accountId != null) {
            hash.put("accountId", String.valueOf(accountId));
            redisTemplate.opsForValue().set(getSessionMapKey(accountId, sessionId), sessionId, 2, TimeUnit.DAYS);
        }

        CookieUtils.store(response, safeProperties.getSession().getSessionIdCookieName(), sessionId);
        return hash;
    }

    public static BoundHashOperations createSession(HttpServletResponse response, String sessionId) {
        return createSession(response, sessionId, null);
    }

    /**
     * 创建已认证的会话
     *
     * @param response
     * @param accountId
     * @return
     */
    public static BoundHashOperations createAuthenticatedSession(HttpServletResponse response, Long accountId) {
        clearLastSession(accountId, WebContext.get().getSessionId());
        return createSession(response, createSessionId(), accountId);
    }

    private static void clearLastSession(Long accountId, String sessionId) {
        redisTemplate.delete(getSessionkey(sessionId));
        if (accountId != null) {
            redisTemplate.delete(getSessionMapKey(accountId, sessionId));
        }
    }

    private static String getSessionkey(String sessionId) {
        return safeProperties.getSession().getSessionKeyPrefix() + sessionId;
    }

    private static String getSessionMapKey(long accountId, String sessionId) {
        return safeProperties.getSession().getSessionMapKeyPrefix() + accountId + ":" + sessionId;
    }

    public static boolean isLogin(String sessionId) {
        BoundHashOperations session = getSession(sessionId);
        return StringUtils.isNotBlank(session.get("accountId"));
    }

    public static boolean isLogin() {
        BoundHashOperations session = getSession();
        return StringUtils.isNotBlank(session.get("accountId"));
    }

    public static boolean touch(String sessionId) {
        Boolean expire = redisTemplate.expire(getSessionkey(sessionId), 2, TimeUnit.DAYS);
        if (BooleanUtils.isNotTrue(expire)) return false;

        if (!isLogin(sessionId)) return true;

        redisTemplate.opsForValue().set(getSessionMapKey(NumberUtils.toLong(getSession(sessionId).get("accountId")), sessionId), sessionId, 2, TimeUnit.DAYS);
        return true;
    }

    private static String getPmsKey(long accountId) {
        return "permissions:account_id:" + accountId;
    }

    private static String getRoleKey(long accountId) {
        return "roles:account_id:" + accountId;
    }

    public static Optional getCurrentAccountId() {
        BoundHashOperations session = getSession(WebContext.get().getSessionId());
        if (StringUtils.isBlank(session.get("accountId"))) return Optional.empty();

        return Optional.of(NumberUtils.toLong(session.get("accountId")));
    }

    public static void clearRoleAndPermission() {
        redisTemplate.delete(safeProperties.getSession().getPermissionKey());
    }

    public static void clearRoleAndPermission(long accountId) {
        redisTemplate.opsForHash().delete(
                safeProperties.getSession().getPermissionKey(),
                getPmsKey(accountId),
                getRoleKey(accountId)
        );
    }

    public static void clearRole(long accountId) {
        redisTemplate.opsForHash().delete(
                safeProperties.getSession().getPermissionKey(),
                getRoleKey(accountId)
        );
    }

    public static void clearPermission(long accountId) {
        redisTemplate.opsForHash().delete(
                safeProperties.getSession().getPermissionKey(),
                getPmsKey(accountId)
        );
    }


    @SuppressWarnings("unchecked")
    public static List getPermission() {
        Optional AccountIdOptional = getCurrentAccountId();
        if (!AccountIdOptional.isPresent()) {
            return Lists.newArrayList();
        }

        BoundHashOperations pmsStore = redisTemplate.boundHashOps(safeProperties.getSession().getPermissionKey());

        String pmsKey = getPmsKey(AccountIdOptional.get());
        if (BooleanUtils.isNotTrue(pmsStore.hasKey(pmsKey))) {
            List pms = authorizingService.listPermission(AccountIdOptional.get());
            if (CollectionUtils.isEmpty(pms)) {
                pms = Lists.newArrayList();
            }
            pmsStore.put(pmsKey, JSON.toJSONString(pms));
        }

        return JSON.parseObject(pmsStore.get(pmsKey), List.class);
    }

    @SuppressWarnings("unchecked")
    public static List getRole() {
        Optional AccountIdOptional = getCurrentAccountId();
        if (!AccountIdOptional.isPresent()) {
            return Lists.newArrayList();
        }

        BoundHashOperations roleStore = redisTemplate.boundHashOps(safeProperties.getSession().getPermissionKey());

        String roleKey = getRoleKey(AccountIdOptional.get());
        if (BooleanUtils.isNotTrue(roleStore.hasKey(roleKey))) {
            List pms = authorizingService.listRole(AccountIdOptional.get());
            if (CollectionUtils.isEmpty(pms)) {
                pms = Lists.newArrayList();
            }
            roleStore.put(roleKey, JSON.toJSONString(pms));
        }

        return JSON.parseObject(roleStore.get(roleKey), List.class);
    }


    public static boolean hasRole(String... role) {
        return getRole().containsAll(Arrays.asList(role));
    }

    public static boolean hasAnyRole(String... role) {
        List role1 = getRole();
        return Stream.of(role).anyMatch(role1::contains);
    }

    public static boolean hasPermission(String... pms) {
        return getPermission().containsAll(Arrays.asList(pms));
    }

    public static boolean hasAnyPermission(String... pms) {
        List pms1 = getPermission();
        return Stream.of(pms).anyMatch(pms1::contains);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy