Search in sources :

Example 1 with AuthenticationRequired

use of net.robinfriedli.aiode.rest.annotations.AuthenticationRequired in project aiode by robinfriedli.

the class RequestInterceptorHandler method preHandle.

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    ThreadContext threadContext = ThreadContext.Current.get();
    threadContext.install(new RequestContext(request));
    try {
        Cookie[] cookies = request.getCookies();
        String sessionId = null;
        if (cookies != null) {
            sessionId = Arrays.stream(cookies).filter(c -> c.getName().equals("botify_session_id")).map(Cookie::getValue).findAny().orElse(null);
        }
        ClientSession clientSession = null;
        ExecutionContext executionContext = null;
        if (sessionId != null) {
            UUID uuid = UUID.fromString(sessionId);
            String remoteAddr = request.getRemoteAddr();
            Optional<ClientSession> existingClientSession = hibernateComponent.invokeWithSession(session -> queryBuilderFactory.find(ClientSession.class).where((cb, root) -> cb.and(cb.equal(root.get("sessionId"), uuid), cb.equal(root.get("ipAddress"), remoteAddr))).build(session).uniqueResultOptional());
            if (existingClientSession.isPresent()) {
                clientSession = existingClientSession.get();
                executionContext = setupExecutionContext(clientSession);
                if (executionContext == null) {
                    response.sendError(403, "Could not connect to guild or user. Either the bot is having connection issues or the bot is longer part of the connected guild or the connected member is no longer part of this guild.");
                    threadContext.clear();
                    return false;
                }
                ExecutionContext.Current.set(executionContext);
            }
        }
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            AuthenticationRequired methodAnnotation = handlerMethod.getMethodAnnotation(AuthenticationRequired.class);
            if (methodAnnotation != null) {
                if (clientSession == null) {
                    response.sendError(403, "This endpoint requires the client to be connected to an active Session");
                    threadContext.clear();
                    return false;
                }
                String[] requiredPermissions = methodAnnotation.requiredPermissions();
                if (requiredPermissions.length > 0) {
                    Member member = executionContext.getMember();
                    boolean unauthorized = Arrays.stream(requiredPermissions).noneMatch(perm -> securityManager.askPermission(perm, member));
                    if (unauthorized) {
                        response.sendError(403, String.format("Member '%s' does not have any of the required permissions: %s", member.getEffectiveName(), String.join(", ", requiredPermissions)));
                        threadContext.clear();
                        return false;
                    }
                }
            }
        }
    } catch (Exception e) {
        response.sendError(500, "Internal server error");
        threadContext.clear();
        throw e;
    }
    return true;
}
Also used : Cookie(javax.servlet.http.Cookie) Arrays(java.util.Arrays) JDA(net.dv8tion.jda.api.JDA) GuildContext(net.robinfriedli.aiode.discord.GuildContext) Member(net.dv8tion.jda.api.entities.Member) TextChannel(net.dv8tion.jda.api.entities.TextChannel) ExecutionContext(net.robinfriedli.aiode.concurrent.ExecutionContext) QueryBuilderFactory(net.robinfriedli.aiode.persist.qb.QueryBuilderFactory) HandlerMethod(org.springframework.web.method.HandlerMethod) HttpServletRequest(javax.servlet.http.HttpServletRequest) Guild(net.dv8tion.jda.api.entities.Guild) SecurityManager(net.robinfriedli.aiode.command.SecurityManager) ThreadContext(net.robinfriedli.aiode.concurrent.ThreadContext) HandlerInterceptor(org.springframework.web.servlet.HandlerInterceptor) Cookie(javax.servlet.http.Cookie) ClientSession(net.robinfriedli.aiode.entities.ClientSession) ShardManager(net.dv8tion.jda.api.sharding.ShardManager) AuthenticationRequired(net.robinfriedli.aiode.rest.annotations.AuthenticationRequired) HttpServletResponse(javax.servlet.http.HttpServletResponse) SessionFactory(org.hibernate.SessionFactory) UUID(java.util.UUID) SpotifyApi(se.michaelthelin.spotify.SpotifyApi) Component(org.springframework.stereotype.Component) GuildManager(net.robinfriedli.aiode.discord.GuildManager) Optional(java.util.Optional) HibernateComponent(net.robinfriedli.aiode.boot.configurations.HibernateComponent) ThreadContext(net.robinfriedli.aiode.concurrent.ThreadContext) HandlerMethod(org.springframework.web.method.HandlerMethod) ExecutionContext(net.robinfriedli.aiode.concurrent.ExecutionContext) ClientSession(net.robinfriedli.aiode.entities.ClientSession) AuthenticationRequired(net.robinfriedli.aiode.rest.annotations.AuthenticationRequired) UUID(java.util.UUID) Member(net.dv8tion.jda.api.entities.Member)

Aggregations

Arrays (java.util.Arrays)1 Optional (java.util.Optional)1 UUID (java.util.UUID)1 Cookie (javax.servlet.http.Cookie)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 JDA (net.dv8tion.jda.api.JDA)1 Guild (net.dv8tion.jda.api.entities.Guild)1 Member (net.dv8tion.jda.api.entities.Member)1 TextChannel (net.dv8tion.jda.api.entities.TextChannel)1 ShardManager (net.dv8tion.jda.api.sharding.ShardManager)1 HibernateComponent (net.robinfriedli.aiode.boot.configurations.HibernateComponent)1 SecurityManager (net.robinfriedli.aiode.command.SecurityManager)1 ExecutionContext (net.robinfriedli.aiode.concurrent.ExecutionContext)1 ThreadContext (net.robinfriedli.aiode.concurrent.ThreadContext)1 GuildContext (net.robinfriedli.aiode.discord.GuildContext)1 GuildManager (net.robinfriedli.aiode.discord.GuildManager)1 ClientSession (net.robinfriedli.aiode.entities.ClientSession)1 QueryBuilderFactory (net.robinfriedli.aiode.persist.qb.QueryBuilderFactory)1 AuthenticationRequired (net.robinfriedli.aiode.rest.annotations.AuthenticationRequired)1