From b84a97fec7e9272db61751b9881004acdf7a4a2c Mon Sep 17 00:00:00 2001 From: hongwei1 Date: Wed, 31 May 2017 13:49:31 +0200 Subject: [PATCH 1/2] fixed the Login "unexpected error" --> "invaild Login Credentials" and added some comments for some methods --- .../code/model/dataAccess/AuthUser.scala | 49 ++++++++++++++----- src/main/scala/code/users/Users.scala | 1 + 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/main/scala/code/model/dataAccess/AuthUser.scala b/src/main/scala/code/model/dataAccess/AuthUser.scala index 586394954..dad634691 100644 --- a/src/main/scala/code/model/dataAccess/AuthUser.scala +++ b/src/main/scala/code/model/dataAccess/AuthUser.scala @@ -540,7 +540,13 @@ import net.liftweb.util.Helpers._ } } - + /** + * This method is belong to AuthUser, it is used for authentication(Login stuff) + * 1 get the user over connector. + * 2 check whether it is existing in AuthUser table in obp side. + * 3 if not existing, will create new AuthUser. + * @return Return the authUser + */ def getUserFromConnector(name: String, password: String):Box[AuthUser] = { Connector.connector.vend.getUser(name, password) match { case Full(InboundUser(extEmail, extPassword, extUsername)) => { @@ -593,6 +599,19 @@ import net.liftweb.util.Helpers._ } //overridden to allow a redirection if login fails + /** + * Success cases: + * case1: user validated && user not locked && user.provider from localhost && password correct --> Login in + * case2: user validated && user not locked && user.provider not localhost && password correct --> Login in + * case3: user from remote && checked over connector --> Login in + * + * Error cases: + * case1: user is locked --> UsernameHasBeenLocked + * case2: user.validated_? --> account.validation.error + * case3: right username but wrong password --> Invalid Login Credentials + * case4: wrong username --> Invalid Login Credentials + * case5: UnKnow error --> UnexpectedErrorDuringLogin + */ override def login = { def loginAction = { if (S.post_?) { @@ -651,6 +670,8 @@ import net.liftweb.util.Helpers._ case _ => homePage } + //This method is used for connector = kafka* || obpjvm* + //It will update the views and createAccountHolder .... registeredUserHelper(user.username) //Check the internal redirect, in case for open redirect issue. // variable redir is from loginRedirect, it is set-up in OAuthAuthorisation.scala as following code: @@ -722,6 +743,10 @@ import net.liftweb.util.Helpers._ LoginAttempt.incrementBadLoginAttempts(username) Empty } + + //If the username is not exiting, throw the error message. + case Empty => S.error(S.?("Invalid Login Credentials")) + case _ => LoginAttempt.incrementBadLoginAttempts(usernameFromGui) S.error(S.?(ErrorMessages.UnexpectedErrorDuringLogin)) // Note we hit this if user has not clicked email validation link @@ -739,8 +764,11 @@ import net.liftweb.util.Helpers._ bind("user", loginXhtml, "submit" -> insertSubmitButton) } - - + + + /** + * The user authentications is not exciting in obp side, it need get the user from south-side + */ def testExternalPassword(usernameFromGui: Box[String], passwordFromGui: Box[String]): Box[Boolean] = { if (connector.startsWith("kafka") || connector == "obpjvm") { val res = for { @@ -757,16 +785,13 @@ import net.liftweb.util.Helpers._ /** * This method will update the views and createAccountHolder .... - * //TODO, maybe not right to save the AccounHolder locally. - * @param name name from HTTP request, - * @param password password from HTTP request - * @return */ def externalUserHelper(name: String, password: String): Box[AuthUser] = { if (connector.startsWith("kafka") || connector == "obpjvm") { for { user <- getUserFromConnector(name, password) u <- Users.users.vend.getUserByUserName(username) + //TODO need more error handle here, I need the exception to debug v <- tryo {Connector.connector.vend.updateUserAccountViews(u)} } yield { user @@ -777,20 +802,20 @@ import net.liftweb.util.Helpers._ /** * This method will update the views and createAccountHolder .... - * //TODO, maybe not right to save the AccounHolder locally. - * @param username - * @return */ def registeredUserHelper(username: String) = { if (connector.startsWith("kafka") || connector == "obpjvm") { for { u <- Users.users.vend.getUserByUserName(username) - //TODO need more error handle here, I need the exception to debug, so set it here. + //TODO need more error handle here, I need the exception to debug v <- Full(Connector.connector.vend.updateUserAccountViews(u)) } yield v } } - + + /** + * find the authUser by author user name(authUser and resourceUser are the same) + */ protected def findUserByUsername(name: String): Box[TheUserType] = { find(By(this.username, name)) } diff --git a/src/main/scala/code/users/Users.scala b/src/main/scala/code/users/Users.scala index a764b04f0..94233f357 100644 --- a/src/main/scala/code/users/Users.scala +++ b/src/main/scala/code/users/Users.scala @@ -27,6 +27,7 @@ trait Users { //resourceuser has two ids: id(Long)and userid_(String), this method use userid_(String) def getUserByUserId(userId : String) : Box[User] + // find ResourceUser by Resourceuser user name def getUserByUserName(userName: String) : Box[ResourceUser] def getUserByEmail(email: String) : Box[List[ResourceUser]] From ce2abe7d6d8660c8716fb90a0db46bf5a08749f1 Mon Sep 17 00:00:00 2001 From: hongwei1 Date: Wed, 31 May 2017 14:30:33 +0200 Subject: [PATCH 2/2] Documented the AuthUser and ResourceUser --- .../code/model/dataAccess/AuthUser.scala | 19 +++++++++++++++++++ .../code/model/dataAccess/ResourceUser.scala | 3 +++ 2 files changed, 22 insertions(+) diff --git a/src/main/scala/code/model/dataAccess/AuthUser.scala b/src/main/scala/code/model/dataAccess/AuthUser.scala index dad634691..45c45b55c 100644 --- a/src/main/scala/code/model/dataAccess/AuthUser.scala +++ b/src/main/scala/code/model/dataAccess/AuthUser.scala @@ -55,6 +55,25 @@ import net.liftweb.util * * * // TODO Document the difference between this and AuthUser / ResourceUser + * + * 1 AuthUser : is used for authentication, only for webpage Login in stuff + * 1) It is MegaProtoUser, has lots of methods for validation username, password, email .... + * Such as lost password, reset password ..... + * Lift have some helper methods to make these things easily. + * + * + * + * 2 ResourceUser: is only a normal LongKeyedMapper + * 1) All the accounts, transactions ,roles, views, accountHolders, customers... should be linked to ResourceUser.userId_ field. + * 2) The consumer keys, tokens are also belong ResourceUser + * + * + * 3 RelationShips: + * 1)When `Sign up` new user --> create AuthUser --> call AuthUser.save() --> create ResourceUser user. + * They share the same username and email. + * 2)AuthUser `user` field as the Foreign Key to link to Resource User. + * one AuthUser <---> one ResourceUser + * * */ class AuthUser extends MegaProtoUser[AuthUser] with Logger { diff --git a/src/main/scala/code/model/dataAccess/ResourceUser.scala b/src/main/scala/code/model/dataAccess/ResourceUser.scala index 805c2c028..a9f855990 100644 --- a/src/main/scala/code/model/dataAccess/ResourceUser.scala +++ b/src/main/scala/code/model/dataAccess/ResourceUser.scala @@ -38,6 +38,9 @@ import code.model.{BankAccountUID, User, UserId, View} import code.views.Views import net.liftweb.common.Full +/** + * Refer to AuthUser, see the difference between AuthUser and ResourceUser + */ class ResourceUser extends LongKeyedMapper[ResourceUser] with User with ManyToMany with OneToMany[Long, ResourceUser]{ def getSingleton = ResourceUser def primaryKeyField = id