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

io.committed.invest.plugin.server.auth.graphql.AuthGraphQlResolver Maven / Gradle / Ivy

The newest version!
package io.committed.invest.plugin.server.auth.graphql;

import java.util.Optional;

import lombok.extern.slf4j.Slf4j;

import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.web.server.WebSession;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import io.committed.invest.core.auth.InvestRoles;
import io.committed.invest.core.graphql.InvestRootContext;
import io.committed.invest.extensions.annotations.GraphQLService;
import io.committed.invest.plugin.server.auth.dao.UserAccount;
import io.committed.invest.plugin.server.auth.dto.User;
import io.committed.invest.plugin.server.auth.utils.AuthUtils;
import io.committed.invest.plugin.server.services.UserService;

import io.leangen.graphql.annotations.GraphQLArgument;
import io.leangen.graphql.annotations.GraphQLContext;
import io.leangen.graphql.annotations.GraphQLMutation;
import io.leangen.graphql.annotations.GraphQLNonNull;
import io.leangen.graphql.annotations.GraphQLQuery;
import io.leangen.graphql.annotations.GraphQLRootContext;

/**
 * GraphQL mutations and queries for authentication actions.
 *
 * 

Though we could use Flux and non-blocking code here, it feels more sensible to be confident * that everything has full executed in inside the functions. */ @GraphQLService @Slf4j public class AuthGraphQlResolver { private final UserService securityService; private final ReactiveAuthenticationManager authenticationManager; public AuthGraphQlResolver( final ReactiveAuthenticationManager authenticationManager, final UserService securityService) { this.authenticationManager = authenticationManager; this.securityService = securityService; } @GraphQLMutation(name = "login", description = "Perform user log in") public Mono login( @GraphQLRootContext final InvestRootContext context, @GraphQLNonNull @GraphQLArgument(name = "username") final String username, @GraphQLNonNull @GraphQLArgument(name = "password") final String password) { try { final Authentication authentication = authenticationManager .authenticate(new UsernamePasswordAuthenticationToken(username, password)) .block(); final WebSession session = context.getSession().block(); final SecurityContextImpl securityContext = new SecurityContextImpl(); securityContext.setAuthentication(authentication); // NOTE: Must be exactly attribute as final WebSessionSecurityContextRepository session.getAttributes().put("USER", securityContext); return Mono.just(AuthUtils.fromAuthentication(authentication)); } catch (final Exception e) { log.warn("Authentication failed for {}", username); return Mono.empty(); } } @GraphQLQuery(name = "session", description = "Get the user's session id") public Mono userSession( @GraphQLContext final User user, @GraphQLRootContext final InvestRootContext context) { return context.getSession().map(WebSession::getId); } @GraphQLQuery(name = "user", description = "Get user details") public Mono user(@GraphQLRootContext final InvestRootContext context) { return context.getAuthentication().map(AuthUtils::fromAuthentication); } @GraphQLQuery(name = "users", description = "Get all users details") public Flux allUsers(@GraphQLRootContext final InvestRootContext context) { return securityService.findAccounts().map(AuthUtils::fromAccount); } @GraphQLMutation(name = "logout", description = "Log out the current session") public Mono logout(@GraphQLRootContext final InvestRootContext context) { return context .getSession() .doOnNext( s -> { s.getAttributes().remove("USER"); s.invalidate(); }) .then(Mono.just(true)); } @GraphQLMutation(name = "saveUser", description = "Create or edit an existing user") public Mono saveUser( @GraphQLRootContext final InvestRootContext context, @GraphQLArgument(name = "user") final User user, @GraphQLArgument(name = "password") final String password) { final Authentication authentication = context.getAuthentication().block(); if (!AuthUtils.hasAuthority(authentication, InvestRoles.ADMINISTRATOR_AUTHORITY)) { log.warn( "Attempt by user {} to create or edit user {}", authentication.getName(), user.getUsername()); return Mono.empty(); } final Optional existingAccount = securityService.getAccount(user.getUsername()).blockOptional(); Mono newUser; if (existingAccount.isPresent()) { newUser = securityService.updateAccount(user.getUsername(), user.getName(), null, user.getRoles()); if (password != null && !password.isEmpty()) { securityService.changePassword(user.getUsername(), password); } } else { newUser = securityService.findOrAddAccount( user.getUsername(), password, user.getName(), null, user.getRoles()); } return newUser.map(AuthUtils::fromAccount); } @GraphQLMutation(name = "changePassword") public void changePassword( @GraphQLRootContext final InvestRootContext context, @GraphQLArgument(name = "username") final String username, @GraphQLArgument(name = "password") final String password) { final Authentication authentication = context.getAuthentication().block(); if (AuthUtils.hasAuthority(authentication, InvestRoles.ADMINISTRATOR_AUTHORITY) || authentication.getName().equals(username)) { securityService.changePassword(username, password); } else { log.warn("Attempt by user {} to change password for {}", authentication.getName(), username); } } @GraphQLMutation(name = "deleteUser", description = "Delete a user") public void deleteUser( @GraphQLRootContext final InvestRootContext context, @GraphQLArgument(name = "username") final String username) { final Authentication authentication = context.getAuthentication().block(); if (AuthUtils.hasAuthority(authentication, InvestRoles.ADMINISTRATOR_AUTHORITY)) { securityService.deleteAccount(username); log.info("Deleted user {}", username); } else { log.warn("Attempt by user {} to delete user {}", authentication.getName(), username); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy