github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/controllers/user/fucntions.go (about)

     1  // Copyright 2023 IAC. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package user
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  
    21  	"net/http"
    22  	"time"
    23  
    24  	"github.com/gin-gonic/gin"
    25  	dbconn "github.com/mdaxf/iac/databases"
    26  
    27  	"github.com/mdaxf/iac/config"
    28  	"github.com/mdaxf/iac/controllers/common"
    29  	"github.com/mdaxf/iac/framework/auth"
    30  	"github.com/mdaxf/iac/logger"
    31  	"golang.org/x/crypto/bcrypt"
    32  )
    33  
    34  // execLogin is a function that handles the login process for a user.
    35  // It takes in the following parameters:
    36  // - ctx: The gin.Context object for handling HTTP requests and responses.
    37  // - username: The username of the user.
    38  // - password: The password of the user.
    39  // - clienttoken: The client token for the user.
    40  // - ClientID: The client ID for the user.
    41  // - Renew: A boolean value indicating whether the session should be renewed.
    42  //
    43  // The function performs the following steps:
    44  // 1. Logs the start time of the function execution.
    45  // 2. Defer a function to log the performance duration of the function.
    46  // 3. If Renew is true, it checks if the session exists in the session cache.
    47  //    - If the session exists, it checks if the session has expired.
    48  //      - If the session has expired, it renews the session and returns the updated user information.
    49  //      - If the session has not expired, it returns an error indicating that the session has already expired.
    50  //    - If the session does not exist, it returns an error indicating that the session renewal failed.
    51  // 4. If Renew is false, it performs the login process.
    52  //    - It queries the database to retrieve the user information.
    53  //    - If the user is found and the password matches, it updates the last sign-on date in the database.
    54  //    - It generates an authentication token for the user and stores it in the session cache.
    55  //    - It returns the user information and the authentication token.
    56  // 5. If any error occurs during the execution, it returns an error response.
    57  
    58  func execLogin(ctx *gin.Context, username string, password string, clienttoken string, ClientID string, Renew bool) {
    59  
    60  	log := logger.Log{ModuleName: logger.API, User: username, ClientID: ClientID, ControllerName: "UserController.execLogin"}
    61  
    62  	startTime := time.Now()
    63  	defer func() {
    64  		elapsed := time.Since(startTime)
    65  		log.PerformanceWithDuration("controllers.user.execLogin", elapsed)
    66  	}()
    67  
    68  	defer func() {
    69  		if err := recover(); err != nil {
    70  			log.Error(fmt.Sprintf("execLogin defer error: %s", err))
    71  			ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
    72  		}
    73  	}()
    74  
    75  	//	log.Debug("Login execution function is called.")
    76  	log.Debug(fmt.Sprintf("login parameters:%s  %s  token: %s  renew:%s", username, password, clienttoken, Renew))
    77  	//	fmt.Println("Session Timeout:", config.SessionCacheTimeout)
    78  	if Renew {
    79  
    80  		user, err := config.SessionCache.Get(ctx, clienttoken)
    81  
    82  		log.Debug(fmt.Sprintf("SessionCache user:%v for token:%s", user, clienttoken))
    83  
    84  		if err != nil {
    85  			log.Error(fmt.Sprintf("SessionCache error:%s for token", err.Error(), clienttoken))
    86  		} else {
    87  			log.Debug(fmt.Sprintf("SessionCache user:%v for token:%s", user, clienttoken))
    88  			if user != nil {
    89  				var tokenuser User
    90  				if val, ok := user.(User); ok {
    91  					tokenuser = val
    92  				} else {
    93  					//	log.Debug(fmt.Sprintf("SessionCache error for token:%s", clienttoken))
    94  					for key, value := range user.(map[string]interface{}) {
    95  						log.Debug(fmt.Sprintf("key:%s value:%v", key, value))
    96  						if key == "token" {
    97  							tokenuser.Token = value.(string)
    98  						} else if key == "expirateon" {
    99  							tokenuser.ExpirateOn = value.(string)
   100  						} else if key == "id" {
   101  							tokenuser.ID = int(value.(int32))
   102  						} else if key == "username" {
   103  							tokenuser.Username = value.(string)
   104  						} else if key == "language" {
   105  							tokenuser.Language = value.(string)
   106  						} else if key == "timezone" {
   107  							tokenuser.TimeZone = value.(string)
   108  						} else if key == "clientid" {
   109  							tokenuser.ClientID = value.(string)
   110  						}
   111  					}
   112  				}
   113  
   114  				if tokenuser.Token == clienttoken {
   115  					layout := "2006-01-02 15:04:05"
   116  					parsedTime, err := time.Parse(layout, tokenuser.ExpirateOn)
   117  					log.Debug(fmt.Sprintf("token %s expirate on:%s expired? %s", tokenuser.Token, parsedTime, parsedTime.Before(time.Now())))
   118  					if err != nil {
   119  						log.Error(fmt.Sprintf("SessionCache error:%s for token:%s", err.Error(), clienttoken))
   120  					} else if parsedTime.Before(time.Now()) {
   121  						log.Debug(fmt.Sprintf("renew the session for user:%s, token: %s", username, tokenuser.Token))
   122  
   123  						token, createdt, expdt, err := auth.Extendexptime(tokenuser.Token)
   124  						if err != nil {
   125  							log.Error(fmt.Sprintf("SessionCache error:%s for token:%s", err.Error(), clienttoken))
   126  						} else {
   127  							ID := tokenuser.ID
   128  							Username := tokenuser.Username
   129  							//	hasedPassword := user.(User).Password
   130  							language := tokenuser.Language
   131  							timezone := tokenuser.TimeZone
   132  							user = User{ID: ID, Username: Username, Language: language, TimeZone: timezone, ClientID: ClientID, CreatedOn: createdt, ExpirateOn: expdt, Token: token}
   133  							config.SessionCache.Delete(ctx, clienttoken)
   134  							config.SessionCache.Put(ctx, token, user, time.Duration(config.SessionCacheTimeout)*time.Second)
   135  							ctx.JSON(http.StatusOK, user)
   136  							return
   137  						}
   138  					}
   139  					log.Debug(fmt.Sprintf("token %s already expried", clienttoken))
   140  				}
   141  			}
   142  
   143  		}
   144  		log.Error(fmt.Sprintf("Renew session failed for user:%s", username))
   145  
   146  		ctx.JSON(http.StatusNotFound, "Renew failed")
   147  
   148  		return
   149  	}
   150  
   151  	//hasedPassword, err := hashPassword(password)
   152  	querystr := fmt.Sprintf(LoginQuery, username)
   153  
   154  	log.Debug(fmt.Sprintf("Query:%s", querystr))
   155  
   156  	iDBTx, err := dbconn.DB.Begin()
   157  	defer iDBTx.Rollback()
   158  
   159  	if err != nil {
   160  		log.Error(fmt.Sprintf("Begin error:%s", err.Error()))
   161  		ctx.JSON(http.StatusInternalServerError, "Login failed")
   162  	}
   163  
   164  	dboperation := dbconn.NewDBOperation(username, iDBTx, "User Login")
   165  	/*
   166  		rows, err := dboperation.Query(querystr)
   167  		defer rows.Close()
   168  		if err != nil {
   169  
   170  			log.Error(fmt.Sprintf("Query error:%s", err.Error()))
   171  			ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
   172  			return
   173  		}
   174  		log.Debug(fmt.Sprintf("Query result:%v", rows))
   175  
   176  	*/
   177  	jdata, err := dboperation.Query_Json(querystr)
   178  
   179  	if err != nil {
   180  
   181  		log.Error(fmt.Sprintf("Query error:%s", err.Error()))
   182  		ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
   183  		return
   184  	}
   185  
   186  	log.Debug(fmt.Sprintf("Query result:%v", jdata))
   187  
   188  	if jdata != nil {
   189  		var ID int
   190  		var Name string
   191  		var FamilyName string
   192  		var storedPassword string
   193  		/*
   194  			err = rows.Scan(&ID, &Name, &FamilyName)
   195  			if err != nil {
   196  				log.Error(fmt.Sprintf("Row Scan error:%s", err.Error()))
   197  				ctx.JSON(http.StatusInternalServerError, "Login failed")
   198  				return
   199  			} */
   200  
   201  		if len(jdata) == 0 {
   202  			log.Error(fmt.Sprintf("User:%s not found", username))
   203  			ctx.JSON(http.StatusNotFound, "Login failed")
   204  			return
   205  		}
   206  
   207  		ID = int(jdata[0]["ID"].(int64))
   208  		Name = jdata[0]["Name"].(string)
   209  		FamilyName = jdata[0]["LastName"].(string)
   210  		storedPassword = jdata[0]["Password"].(string)
   211  		language := jdata[0]["LanguageCode"].(string)
   212  		timezone := jdata[0]["TimeZoneCode"].(string)
   213  
   214  		if jdata[0]["Password"] != nil && storedPassword != "" {
   215  			err = bcrypt.CompareHashAndPassword([]byte(storedPassword), []byte(password))
   216  			if err != nil {
   217  				log.Error(fmt.Sprintf("Password compare error:%s", err.Error()))
   218  				ctx.JSON(http.StatusNotFound, "Login failed")
   219  				return
   220  			}
   221  		}
   222  
   223  		log.Debug(fmt.Sprintf("ID:%d  Name:%s  FamilyName:%s", ID, Name, FamilyName))
   224  
   225  		Columns := []string{"LastSignOnDate", "UpdatedOn", "UpdatedBy"}
   226  		Values := []string{time.Now().UTC().Format("2006-01-02 15:04:05"), time.Now().UTC().Format("2006-01-02 15:04:05"), username}
   227  		datatypes := []int{0, 0, 0}
   228  		Wherestr := fmt.Sprintf("ID= %d", ID)
   229  
   230  		index, errr := dboperation.TableUpdate(TableName, Columns, Values, datatypes, Wherestr)
   231  
   232  		if errr != nil {
   233  			log.Error(fmt.Sprintf("TableUpdate error:%s", errr.Error()))
   234  			ctx.JSON(http.StatusInternalServerError, "Login failed")
   235  			return
   236  		}
   237  		log.Debug(fmt.Sprintf("index:%d", index))
   238  
   239  		iDBTx.Commit()
   240  
   241  		token, createdt, expdt, err := auth.Generate_authentication_token(string(rune(ID)), username, ClientID)
   242  
   243  		sessionid := token
   244  		exist, err := config.SessionCache.IsExist(ctx, sessionid)
   245  
   246  		if err != nil && exist {
   247  			config.SessionCache.Delete(ctx, sessionid)
   248  
   249  		}
   250  		user := User{ID: ID, Username: username, Language: language, TimeZone: timezone, ClientID: ClientID, CreatedOn: createdt, ExpirateOn: expdt, Token: token}
   251  
   252  		log.Debug(fmt.Sprintf("user:%v", user))
   253  
   254  		config.SessionCache.Put(ctx, sessionid, user, time.Duration(config.SessionCacheTimeout)*time.Second)
   255  		log.Debug(fmt.Sprintf("User:%s login successful!", user))
   256  
   257  		ctx.JSON(http.StatusOK, user)
   258  		return
   259  	}
   260  
   261  	iDBTx.Rollback()
   262  	log.Error(fmt.Sprintf("Login failed for user:%s", username))
   263  
   264  	ctx.JSON(http.StatusNotFound, "Login failed")
   265  
   266  }
   267  
   268  // getUserImage retrieves the user's image URL from the database.
   269  // It takes the username and client ID as parameters and returns the image URL as a string.
   270  // If an error occurs during the execution, it returns an error.
   271  
   272  func getUserImage(username string, clientid string) (string, error) {
   273  	log := logger.Log{ModuleName: logger.API, User: username, ClientID: clientid, ControllerName: "UserController.getUserImage"}
   274  	startTime := time.Now()
   275  	defer func() {
   276  		elapsed := time.Since(startTime)
   277  		log.PerformanceWithDuration("controllers.user.getUserImage", elapsed)
   278  	}()
   279  	/*
   280  		defer func() {
   281  			if err := recover(); err != nil {
   282  				log.Error(fmt.Sprintf("getUserImage defer error: %s", err))
   283  				//ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
   284  			}
   285  		}()
   286  	*/
   287  	log.Debug("Get User Image execution function is called.")
   288  
   289  	querystr := fmt.Sprintf(GetUserImageQuery, username)
   290  
   291  	log.Debug(fmt.Sprintf("Get User image Query:%s", querystr))
   292  
   293  	iDBTx, err := dbconn.DB.Begin()
   294  	defer iDBTx.Rollback()
   295  
   296  	if err != nil {
   297  		log.Error(fmt.Sprintf("Begin error:%s", err.Error()))
   298  		return "", err
   299  	}
   300  
   301  	dboperation := dbconn.NewDBOperation(username, iDBTx, "User Login")
   302  
   303  	jdata, err := dboperation.Query_Json(querystr)
   304  
   305  	if err != nil {
   306  
   307  		log.Error(fmt.Sprintf("Query error:%s", err.Error()))
   308  		return "", err
   309  
   310  	}
   311  
   312  	log.Debug(fmt.Sprintf("Query result:%v", jdata))
   313  
   314  	if jdata != nil {
   315  		var PictureUrl string
   316  
   317  		if len(jdata) == 0 {
   318  			return "", nil
   319  		}
   320  
   321  		if jdata[0]["PictureUrl"] == nil {
   322  			return "", nil
   323  		}
   324  
   325  		PictureUrl = jdata[0]["PictureUrl"].(string)
   326  
   327  		iDBTx.Commit()
   328  
   329  		log.Debug(fmt.Sprintf("PictureUrl:%s", PictureUrl))
   330  
   331  		return PictureUrl, nil
   332  
   333  	}
   334  	return "", nil
   335  }
   336  
   337  // getUserMenus retrieves the menus for a user based on the provided parameters.
   338  // It takes the userID, isMobile flag, parentID, username, and clientid as input.
   339  // The function returns a slice of maps representing the menus and an error if any.
   340  
   341  func getUserMenus(userID int, isMobile bool, parentID int, username string, clientid string) ([]map[string]interface{}, error) {
   342  	log := logger.Log{ModuleName: logger.API, User: username, ClientID: clientid, ControllerName: "UserController"}
   343  
   344  	startTime := time.Now()
   345  	defer func() {
   346  		elapsed := time.Since(startTime)
   347  		log.PerformanceWithDuration("controllers.user.getUserMenus", elapsed)
   348  	}()
   349  
   350  	defer func() {
   351  		if err := recover(); err != nil {
   352  			log.Error(fmt.Sprintf("getUserMenus defer error: %s", err))
   353  			//ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
   354  		}
   355  	}()
   356  
   357  	log.Debug("get user menus execution function is called.")
   358  
   359  	Mobile := 0
   360  	Desktop := 1
   361  
   362  	if isMobile {
   363  		Mobile = 1
   364  		Desktop = 0
   365  	}
   366  
   367  	querystr := fmt.Sprintf(GetUserMenusQuery, userID, Mobile, Desktop, parentID, userID)
   368  
   369  	log.Debug(fmt.Sprintf("Query:%s", querystr))
   370  
   371  	iDBTx, err := dbconn.DB.Begin()
   372  
   373  	if err != nil {
   374  		log.Error(fmt.Sprintf("Begin error:%s", err.Error()))
   375  		return nil, err
   376  	}
   377  
   378  	defer iDBTx.Rollback()
   379  
   380  	dboperation := dbconn.NewDBOperation(strconv.Itoa(userID), iDBTx, "User Menus")
   381  
   382  	jdata, err := dboperation.Query_Json(querystr)
   383  
   384  	if err != nil {
   385  		log.Error(fmt.Sprintf("Query menu error:%s", err.Error()))
   386  		return jdata, err
   387  	}
   388  
   389  	log.Debug(fmt.Sprintf("Query result:%v", jdata))
   390  
   391  	return jdata, nil
   392  }
   393  
   394  // execChangePassword is a function that handles the execution of changing a user's password.
   395  // It takes the following parameters:
   396  // - ctx: The gin.Context object for handling HTTP requests and responses.
   397  // - username: The username of the user whose password is being changed.
   398  // - oldpassword: The old password of the user.
   399  // - newpassword: The new password to be set for the user.
   400  // - clientid: The client ID associated with the user.
   401  // It returns an error if any error occurs during the password change process.
   402  
   403  func execChangePassword(ctx *gin.Context, username string, oldpassword string, newpassword string, clientid string) error {
   404  	log := logger.Log{ModuleName: logger.API, User: username, ClientID: clientid, ControllerName: "UserController"}
   405  	startTime := time.Now()
   406  	defer func() {
   407  		elapsed := time.Since(startTime)
   408  		log.PerformanceWithDuration("controllers.user.execChangePassword", elapsed)
   409  	}()
   410  
   411  	defer func() {
   412  		if err := recover(); err != nil {
   413  			log.Error(fmt.Sprintf("execChangePassword defer error: %s", err))
   414  			//ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
   415  		}
   416  	}()
   417  
   418  	log.Debug("execChangePassword execution function is called.")
   419  
   420  	result, jdata, err := validatePassword(username, oldpassword)
   421  
   422  	if err != nil {
   423  		log.Error(fmt.Sprintf("validatePassword error:%s", err.Error()))
   424  
   425  		ctx.JSON(http.StatusInternalServerError, "Validate old password failed")
   426  		return err
   427  	}
   428  
   429  	if result == false {
   430  		log.Error(fmt.Sprintf("validatePassword error:%s", err.Error()))
   431  		ctx.JSON(http.StatusInternalServerError, "Validate old password failed")
   432  		return err
   433  	}
   434  
   435  	hashedPassword, err := hashPassword(newpassword)
   436  
   437  	if jdata != nil {
   438  
   439  		ID := int(jdata[0]["ID"].(int64))
   440  
   441  		log.Debug(fmt.Sprintf("user ID:%d  new hashed password: %s ", ID, hashedPassword))
   442  
   443  		Columns := []string{"Password", "PasswordLastChangeDate", "UpdatedOn", "UpdatedBy"}
   444  		Values := []string{hashedPassword, time.Now().Format("2006-01-02 15:04:05"), time.Now().Format("2006-01-02 15:04:05"), username}
   445  		datatypes := []int{0, 0, 0}
   446  		Wherestr := fmt.Sprintf("ID= %d", ID)
   447  
   448  		iDBTx, err := dbconn.DB.Begin()
   449  		defer iDBTx.Rollback()
   450  
   451  		if err != nil {
   452  			log.Error(fmt.Sprintf("Begin error:%s", err.Error()))
   453  			ctx.JSON(http.StatusInternalServerError, "Change password failed")
   454  			return err
   455  		}
   456  
   457  		dboperation := dbconn.NewDBOperation(username, iDBTx, "User ChangePassword")
   458  
   459  		index, errr := dboperation.TableUpdate(TableName, Columns, Values, datatypes, Wherestr)
   460  
   461  		if errr != nil {
   462  			log.Error(fmt.Sprintf("TableUpdate error:%s", errr.Error()))
   463  			ctx.JSON(http.StatusInternalServerError, "Change password failed")
   464  			return errr
   465  		}
   466  
   467  		if index == 0 {
   468  			log.Error(fmt.Sprintf("TableUpdate error:%s", errr.Error()))
   469  			ctx.JSON(http.StatusInternalServerError, "Change password failed")
   470  			return errr
   471  		}
   472  
   473  		iDBTx.Commit()
   474  		ctx.JSON(http.StatusOK, "OK")
   475  		return nil
   476  	}
   477  
   478  	ctx.JSON(http.StatusInternalServerError, "Change password failed")
   479  	return nil
   480  }
   481  
   482  // execLogout is a function that handles the logout process for a user.
   483  // It takes a gin.Context object and a token string as parameters.
   484  // It returns a string "OK" and an error if any.
   485  
   486  func execLogout(ctx *gin.Context, token string) (string, error) {
   487  	log := logger.Log{ModuleName: logger.API, User: "System", ControllerName: "UserController"}
   488  
   489  	startTime := time.Now()
   490  	defer func() {
   491  		elapsed := time.Since(startTime)
   492  		log.PerformanceWithDuration("controllers.user.execLogout", elapsed)
   493  	}()
   494  
   495  	defer func() {
   496  		if err := recover(); err != nil {
   497  			log.Error(fmt.Sprintf("execLogout defer error: %s", err))
   498  			ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
   499  		}
   500  	}()
   501  	ID, user, clientid, err := common.GetRequestUser(ctx)
   502  	if err != nil {
   503  		log.Error(fmt.Sprintf("Get user information Error: %v", err))
   504  
   505  		return "", err
   506  	}
   507  	log.ClientID = clientid
   508  	log.User = user
   509  	log.Debug(fmt.Sprintf("execLogout execution function is called. token: %s, %s ", token, ID))
   510  
   511  	Columns := []string{"LastSignOffDate", "UpdatedOn", "UpdatedBy"}
   512  	Values := []string{time.Now().UTC().Format("2006-01-02 15:04:05"), time.Now().UTC().Format("2006-01-02 15:04:05"), user}
   513  	datatypes := []int{0, 0, 0}
   514  	Wherestr := fmt.Sprintf("LoginName= '%s'", user)
   515  
   516  	iDBTx, err := dbconn.DB.Begin()
   517  	defer iDBTx.Rollback()
   518  
   519  	if err != nil {
   520  		log.Error(fmt.Sprintf("Begin error:%s", err.Error()))
   521  		ctx.JSON(http.StatusInternalServerError, "Login failed")
   522  	}
   523  
   524  	dboperation := dbconn.NewDBOperation(user, iDBTx, "User Logout")
   525  
   526  	index, errr := dboperation.TableUpdate(TableName, Columns, Values, datatypes, Wherestr)
   527  
   528  	if errr != nil {
   529  		log.Error(fmt.Sprintf("TableUpdate error:%s", errr.Error()))
   530  		ctx.JSON(http.StatusInternalServerError, "Logout failed")
   531  		return "", errr
   532  	}
   533  	log.Debug(fmt.Sprintf("index:%d", index))
   534  
   535  	config.SessionCache.Delete(ctx, token)
   536  
   537  	iDBTx.Commit()
   538  
   539  	return "OK", nil
   540  }
   541  
   542  // hashPassword takes a password string and returns the hashed password string.
   543  // It uses bcrypt.GenerateFromPassword to generate a secure hash of the password.
   544  // The bcrypt.DefaultCost is used to determine the cost factor of the hashing algorithm.
   545  // Returns the hashed password string and any error encountered during the hashing process.
   546  
   547  func hashPassword(password string) (string, error) {
   548  	hashedPasswordBytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
   549  	if err != nil {
   550  		return "", err
   551  	}
   552  
   553  	hashedPassword := string(hashedPasswordBytes)
   554  	return hashedPassword, nil
   555  }
   556  
   557  // validatePassword validates the password for a given username.
   558  // It returns a boolean indicating whether the password is valid,
   559  // a slice of maps containing user data if the password is valid,
   560  // and an error if any error occurs during the validation process.
   561  
   562  func validatePassword(username string, password string) (bool, []map[string]interface{}, error) {
   563  	log := logger.Log{ModuleName: logger.API, User: "System", ControllerName: "UserController"}
   564  
   565  	startTime := time.Now()
   566  	defer func() {
   567  		elapsed := time.Since(startTime)
   568  		log.PerformanceWithDuration("controllers.user.validatePassword", elapsed)
   569  	}()
   570  
   571  	defer func() {
   572  		if err := recover(); err != nil {
   573  			log.Error(fmt.Sprintf("validatePassword defer error: %s", err))
   574  			//	ctx.JSON(http.StatusBadRequest, gin.H{"error": err})
   575  		}
   576  	}()
   577  
   578  	log.Debug(fmt.Sprintf("validate password function is called. username: %s ", username))
   579  
   580  	//	hashedPassword, err := hashPassword(password)
   581  
   582  	jdata := []map[string]interface{}{}
   583  	/*
   584  		if err != nil {
   585  			log.Error(fmt.Sprintf("hashPassword error:%s", err.Error()))
   586  			return false, nil, err
   587  		}
   588  	*/
   589  	querystr := fmt.Sprintf(LoginQuery, username)
   590  
   591  	log.Debug(fmt.Sprintf("Query:%s", querystr))
   592  
   593  	iDBTx, err := dbconn.DB.Begin()
   594  	defer iDBTx.Rollback()
   595  
   596  	if err != nil {
   597  		log.Error(fmt.Sprintf("Begin error:%s", err.Error()))
   598  		return false, nil, err
   599  	}
   600  
   601  	dboperation := dbconn.NewDBOperation(username, iDBTx, "User Login")
   602  
   603  	jdata, err = dboperation.Query_Json(querystr)
   604  
   605  	if err != nil {
   606  
   607  		log.Error(fmt.Sprintf("Query error:%s", err.Error()))
   608  		return false, nil, err
   609  
   610  	}
   611  
   612  	log.Debug(fmt.Sprintf("Query result:%v", jdata))
   613  
   614  	if jdata != nil {
   615  
   616  		iDBTx.Commit()
   617  
   618  		if len(jdata) == 0 {
   619  			return false, nil, err
   620  		}
   621  
   622  		storedPassword := jdata[0]["Password"].(string)
   623  
   624  		if storedPassword == "" || jdata[0]["Password"] == nil {
   625  			return true, jdata, nil
   626  		}
   627  
   628  		err := bcrypt.CompareHashAndPassword([]byte(storedPassword), []byte(password))
   629  		if err != nil {
   630  			log.Error(fmt.Sprintf("CompareHashAndPassword error:%s", err.Error()))
   631  			return false, nil, err
   632  		}
   633  
   634  		return true, jdata, nil
   635  	}
   636  	return false, nil, nil
   637  }