feature/Add user init action after logon WIP 1

This commit is contained in:
Marko Milić 2021-11-24 17:10:47 +01:00
parent 80349adbdd
commit 5bf4467ec5
5 changed files with 52 additions and 3 deletions

View File

@ -115,6 +115,8 @@ object DirectLogin extends RestHelper with MdcLoggable {
val authUser = AuthUser.findUserByUsernameLocally(resourceUser.name).openOrThrowException(s"$InvalidDirectLoginParameters can not find the auth user!")
AuthUser.grantEntitlementsToUseDynamicEndpointsInSpaces(authUser)
AuthUser.grantEmailDomainEntitlementsToUser(authUser)
// User init actions
AfterApiAuth.userGuiLogonInitAction(Full(authUser))
} catch {
case e: Throwable => // error handling, found wrong props value as early as possible.
this.logger.error(s"directLogin.grantEntitlementsToUseDynamicEndpointsInSpacesInDirectLogin throw exception, details: $e" );

View File

@ -29,7 +29,7 @@ package code.api
import java.net.HttpURLConnection
import code.api.util.APIUtil._
import code.api.util.{APIUtil, ErrorMessages, JwtUtil}
import code.api.util.{APIUtil, AfterApiAuth, ErrorMessages, JwtUtil}
import code.consumer.Consumers
import code.loginattempts.LoginAttempt
import code.model.{AppType, Consumer}
@ -126,6 +126,8 @@ object OpenIdConnect extends OBPRestHelper with MdcLoggable {
AuthUser.grantEmailDomainEntitlementsToUser(authUser)
// Grant roles according to the props email_domain_to_space_mappings
AuthUser.grantEntitlementsToUseDynamicEndpointsInSpaces(authUser)
// User init actions
AfterApiAuth.userGuiLogonInitAction(Full(authUser))
// Consumer
getOrCreateConsumer(idToken, user.userId) match {
case Full(consumer) =>

View File

@ -2769,9 +2769,11 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
val userIsLockedOrDeleted: Future[(Box[User], Option[CallContext])] = AfterApiAuth.checkUserIsDeletedOrLocked(res)
// Check Rate Limiting
val resultWithRateLimiting: Future[(Box[User], Option[CallContext])] = AfterApiAuth.checkRateLimiting(userIsLockedOrDeleted)
// User init actions
val resultWithUserInitActions: Future[(Box[User], Option[CallContext])] = AfterApiAuth.userApiLogonInitAction(resultWithRateLimiting)
// Update Call Context
resultWithRateLimiting map {
resultWithUserInitActions map {
x => (x._1, ApiSession.updateCallContext(Spelling(spelling), x._2))
} map {
x => (x._1, x._2.map(_.copy(implementedInVersion = implementedInVersion)))

View File

@ -5,15 +5,52 @@ import java.util.Date
import code.api.util.ErrorMessages.{UserIsDeleted, UsernameHasBeenLocked}
import code.api.util.RateLimitingJson.CallLimit
import code.loginattempts.LoginAttempt
import code.model.dataAccess.AuthUser
import code.ratelimiting.{RateLimiting, RateLimitingDI}
import code.util.Helper.MdcLoggable
import com.openbankproject.commons.model.User
import net.liftweb.common.{Box, Empty, Failure, Full}
import com.openbankproject.commons.ExecutionContext.Implicits.global
import net.liftweb.mapper.By
import scala.concurrent.Future
object AfterApiAuth {
object AfterApiAuth extends MdcLoggable{
/**
* This function is used to execute actions after an user is authenticated via GUI
* Types of authentication: GUI logon(OpenID Connect and OAuth1.0a)
* @param user the authenticated user
*/
def userGuiLogonInitAction(user: Box[AuthUser]) = {
user.map { u => // Init actions
logger.info("AfterApiAuth.userGuiLogonInitAction started successfully")
} match {
case Full(_) => logger.warn("AfterApiAuth.userGuiLogonInitAction completed successfully")
case userInitActionFailure => logger.warn("AfterApiAuth.userGuiLogonInitAction: " + userInitActionFailure)
}
}
/**
* This function is used to execute actions after an user is authenticated via API
* Types of authentication: Direct Login, OpenID Connect, OAuth1.0a, Direct Login, DAuth and Gateway Login
*/
def userApiLogonInitAction(result: Future[(Box[User], Option[CallContext])]): Future[(Box[User], Option[CallContext])] = {
logger.info("AfterApiAuth.userApiLogonInitAction started successfully")
for {
(user: Box[User], cc) <- result
} yield {
user match {
case Full(u) => // There is a user. Apply init actions
val authUser: Box[AuthUser] = AuthUser.find(By(AuthUser.user, u.userPrimaryKey.value))
userGuiLogonInitAction(authUser)
(user, cc)
case userInitActionFailure => // There is no user. Just forward the result.
logger.warn("AfterApiAuth.userApiLogonInitAction: " + userInitActionFailure)
(user, cc)
}
}
}
def checkUserIsDeletedOrLocked(res: Future[(Box[User], Option[CallContext])]): Future[(Box[User], Option[CallContext])] = {
for {
(user: Box[User], cc) <- res

View File

@ -996,6 +996,8 @@ def restoreSomeSessions(): Unit = {
// Reset any bad attempt
LoginAttempt.resetBadLoginAttempts(usernameFromGui)
val preLoginState = capturePreLoginState()
// User init actions
AfterApiAuth.userGuiLogonInitAction(Full(user))
logger.info("login redirect: " + loginRedirect.get)
val redirect = redirectUri()
checkInternalRedirectAndLogUseIn(preLoginState, redirect, user)
@ -1021,6 +1023,8 @@ def restoreSomeSessions(): Unit = {
//This method is used for connector = kafka* || obpjvm*
//It will update the views and createAccountHolder ....
registeredUserHelper(user.username.get)
// User init actions
AfterApiAuth.userGuiLogonInitAction(Full(user))
checkInternalRedirectAndLogUseIn(preLoginState, redirect, user)
// If user cannot be found locally, try to authenticate user via connector
@ -1034,6 +1038,8 @@ def restoreSomeSessions(): Unit = {
externalUserHelper(usernameFromGui, passwordFromGui) match {
case Full(user: AuthUser) =>
LoginAttempt.resetBadLoginAttempts(usernameFromGui)
// User init actions
AfterApiAuth.userGuiLogonInitAction(Full(user))
checkInternalRedirectAndLogUseIn(preLoginState, redirect, user)
case _ =>
LoginAttempt.incrementBadLoginAttempts(username.get)