// Implementation of Auth Serice that will eventually retrieve login information // from the auth database. unit Auth.ServiceImpl; interface uses XData.Service.Common, XData.Server.Module, Auth.Service, Auth.Database, Uni, Data.DB, System.Hash; type [ServiceImplementation] TAuthService = class(TInterfacedObject, IAuthService) strict private authDB: TAuthDatabase; function GetQuery: TUniQuery; private userName: string; userFullName: string; userId: string; userPerspectiveID: string; userQBID: string; userAccessType: string; userEmail: string; userStatus: string; procedure AfterConstruction; override; procedure BeforeDestruction; override; property Query: TUniQuery read GetQuery; function CheckUser(const user, password: string): Integer; public function Login(const user, password: string): string; function VerifyVersion(version: string): string; end; implementation uses System.SysUtils, System.DateUtils, System.Generics.Collections, Bcl.JOSE.Core.Builder, Bcl.JOSE.Core.JWT, Aurelius.Global.Utils, XData.Sys.Exceptions, Common.Logging, Common.Config, uLibrary; { TLoginService } procedure TAuthService.AfterConstruction; begin inherited; authDB := TAuthDatabase.Create(nil); end; procedure TAuthService.BeforeDestruction; begin authDB.Free; inherited; end; function TAuthService.GetQuery: TUniQuery; begin Result := authDB.uq; end; function TAuthService.VerifyVersion(version: string): string; begin if( version <> '1.0.0' ) then begin Logger.Log( 2, 'TLoginService.GetAgenciesConfigList - Error: wrong ver!' ); result := 'Error - You have the wrong version! Please clear your cache and refresh!'; Exit; end; result := ''; end; function TAuthService.Login(const user, password: string): string; // Login verification: currently checks if logins are the same or if the user // is admin, checks for admin password. Eventually will do a database lookup // instead. If the user has a JWT token they do not need to login. // Potential error occuring when logging in after you have already logged in // webcharms. var userState: Integer; JWT: TJWT; begin Logger.Log(1, Format( 'AuthService.Login - User: "%s"', [User])); userState := CheckUser( user, password ); if userState = 0 then raise EXDataHttpUnauthorized.Create('Invalid username or password'); if userState = 1 then raise EXDataHttpUnauthorized.Create('User does not exist!'); if userState = 2 then raise EXDataHttpUnauthorized.Create('User not active!'); JWT := TJWT.Create; try JWT.Claims.JWTId := LowerCase(Copy(TUtils.GuidToVariant(TUtils.NewGuid), 2, 36)); JWT.Claims.IssuedAt := Now; JWT.Claims.Expiration := IncHour(Now, 24); JWT.Claims.SetClaimOfType<string>('user_name', userName); JWT.Claims.SetClaimOfType<string>('user_fullname', userFullName); JWT.Claims.SetClaimOfType<string>('user_id', userId); JWT.Claims.SetClaimOfType<string>('user_perspective_id', userPerspectiveID); JWT.Claims.SetClaimOfType<string>('user_status', userStatus); JWT.Claims.SetClaimOfType<string>('user_email', userEmail); JWT.Claims.SetClaimOfType<string>('user_qb_id', userQBID); JWT.Claims.SetClaimOfType<string>('user_access_type', userAccessType); Result := TJOSE.SHA256CompactToken(serverConfig.jwtTokenSecret, JWT); finally JWT.Free; end; end; function TAuthService.CheckUser(const user, password: string): Integer; var userStr: string; SQL: string; date_created: string; checkString: string; begin //authDB := TAuthDatabase.Create(nil); Result := 0; //Logger.Log( 3, Format('AuthService.CheckUser - User: "%s"', [user]) ); SQL := 'select * from users where USER_NAME = ' + QuotedStr(user); DoQuery(authDB.uq, SQL); if authDB.uq.IsEmpty then begin Result := 1; //user does not exist, replace this with 0 for more security end else if ( authDB.uq.FieldByName('STATUS').AsString <> 'ACTIVE' ) then Result := 2 // user is not active else begin //date_created := authDB.uq.FieldByName('date_created').AsString; //checkString := THashSHA2.GetHashString(date_created + password, THashSHA2.TSHA2Version.SHA512).ToUpper; if password = authDB.uq.FieldByName('PASSWORD').AsString then begin userName := user; userFullName:= authDB.uq.FieldByName('NAME').AsString;; userId := authDB.uq.FieldByName('USER_ID').AsString; userStatus := authDB.uq.FieldByName('STATUS').AsString; userPerspectiveID := authDB.uq.FieldByName('PERSPECTIVE_ID').AsString; userEmail := authDB.uq.FieldByName('EMAIL').AsString; userQBID := authDB.uq.FieldByName('QB_ID').AsString; userAccessType := authDB.uq.FieldByName('ACCESS_TYPE').AsString; //Logger.Log( 3, Format('AuthDB.SetLoginAuditEntry: "%s"', [user]) ); //AuthDB.SetLoginAuditEntry( userStr ); Result := 3; // Succcess end else Result := 0; // invalid password end; end; initialization RegisterServiceType(TAuthService); end.