/// <summary>
        /// This method fetches role based functions for the current user
        /// </summary>
        /// <param name="userUnitInfo">user unit information</param>
        /// <returns>functions available for current user</returns>
        public async Task <List <RoleAccessDTO> > GetRoleBasedAccessFunctions(UserUnitInfoDTO userUnitInfo)
        {
            string methodName = typeof(ActionManagerBusinessService) + "." + nameof(GetRoleBasedAccessFunctions);

            using (loggingHelper.RMTraceManager.StartTrace("BusinessService.GetRoleBasedAccessFunctions"))
            {
                loggingHelper.LogMethodEntry(methodName, priority, entryEventId);

                // mapping public DTO to dataDTO
                UserUnitInfoDataDTO userUnitInfoDataDTO = GenericMapper.Map <UserUnitInfoDTO, UserUnitInfoDataDTO>(userUnitInfo);

                var roleAccessDataDto = await actionManagerDataService.GetRoleBasedAccessFunctions(userUnitInfoDataDTO);

                loggingHelper.LogMethodExit(methodName, priority, exitEventId);

                // mapping dataDTO to public DTO
                List <RoleAccessDTO> roleAccessDTO = GenericMapper.MapList <RoleAccessDataDTO, RoleAccessDTO>(roleAccessDataDto);
                return(roleAccessDTO);
            }
        }
        /// <summary>
        /// This method fetches Unit information for which user has access
        /// </summary>
        /// <param name="userName">username</param>
        /// <param name="locationId">unit id</param>
        /// <returns>unit details</returns>
        public async Task <UserUnitInfoDTO> GetUserUnitInfo(string userName, Guid locationId)
        {
            string methodName = typeof(ActionManagerBusinessService) + "." + nameof(GetUserUnitInfo);

            using (loggingHelper.RMTraceManager.StartTrace("BusinessService.GetUserUnitInfo"))
            {
                loggingHelper.LogMethodEntry(methodName, priority, entryEventId);
                var userUnitDetails = await actionManagerDataService.GetUserUnitInfo(userName, locationId);

                // Get the Unit details from reference data if current user has access to the units above mail center
                if (userUnitDetails == null)
                {
                    userUnitDetails = await actionManagerDataService.GetUserUnitInfoFromReferenceData(userName, locationId);
                }

                // mapping dataDTO to public DTO
                UserUnitInfoDTO userUnitInfoDTO = GenericMapper.Map <UserUnitInfoDataDTO, UserUnitInfoDTO>(userUnitDetails);
                loggingHelper.LogMethodExit(methodName, priority, exitEventId);

                return(userUnitInfoDTO);
            }
        }
        public async Task <List <RoleAccessDTO> > GetRoleBasedAccessFunctions(UserUnitInfoDTO userUnitInfo)
        {
            using (loggingHelper.RMTraceManager.StartTrace("DataService.GetRoleBasedAccessFunctions"))
            {
                string methodName = MethodHelper.GetActualAsyncMethodName();
                loggingHelper.Log(methodName + LoggerTraceConstants.COLON + LoggerTraceConstants.MethodExecutionStarted, TraceEventType.Verbose, null, LoggerTraceConstants.Category, LoggerTraceConstants.ActionManagerAPIPriority, LoggerTraceConstants.ActionManagerDataServiceMethodEntryEventId, LoggerTraceConstants.Title);

                var roleAccessDto = await DataContext.AccessFunctions.AsNoTracking()
                                    .Where(x => x.UserName.Equals(userUnitInfo.UserName) && x.Unit_GUID.Equals(userUnitInfo.UnitGuid))
                                    .Select(x => new RoleAccessDTO
                {
                    RoleName     = x.RoleName,
                    Unit_GUID    = x.Unit_GUID,
                    UserName     = x.UserName,
                    FunctionName = x.FunctionName,
                    ActionName   = x.ActionName,
                    UserId       = x.UserId
                }).ToListAsync();

                loggingHelper.Log(methodName + LoggerTraceConstants.COLON + LoggerTraceConstants.MethodExecutionCompleted, TraceEventType.Verbose, null, LoggerTraceConstants.Category, LoggerTraceConstants.ActionManagerAPIPriority, LoggerTraceConstants.ActionManagerDataServiceMethodExitEventId, LoggerTraceConstants.Title);
                return(roleAccessDto);
            }
        }
        /// <summary>
        /// This method generates token depending on the user and selected unit
        /// </summary>
        /// <param name="context">http context</param>
        /// <returns>Token</returns>
        private async Task GenerateToken(HttpContext context)
        {
            try
            {
                string methodName = typeof(TokenProviderMiddleware) + "." + nameof(GenerateToken);
                using (loggingHelper.RMTraceManager.StartTrace("Middleware.GenerateToken"))
                {
                    loggingHelper.LogMethodEntry(methodName, priority, entryEventId);
                    var    username = context.Request.Form["username"];
                    Guid   unitGuid;
                    string unitType = string.Empty;
                    string unitName = string.Empty;
                    bool   isGuid   = Guid.TryParse(context.Request.Form["UnitGuid"], out unitGuid);

                    var identity = await options.IdentityResolver(username, unitGuid != null?unitGuid.ToString() : string.Empty);

                    if (identity == null)
                    {
                        context.Response.StatusCode = 400;
                        await context.Response.WriteAsync("Invalid username or password.");

                        return;
                    }

                    // Get the Unit dtails for current user.
                    UserUnitInfoDTO userUnitDetails = await actionManagerBusinessService.GetUserUnitInfo(username, unitGuid);

                    // unitGuid would be empty while loading the application for first time for the current session for the current user
                    if (unitGuid == Guid.Empty)
                    {
                        unitGuid = userUnitDetails.LocationId;
                    }

                    UserUnitInfoDTO userUnitInfoDto = new UserUnitInfoDTO
                    {
                        UserName   = username,
                        LocationId = unitGuid,
                        UnitType   = userUnitDetails.UnitType,
                        UnitName   = userUnitDetails.UnitName
                    };

                    var roleAccessDTO = await actionManagerBusinessService.GetRoleBasedAccessFunctions(userUnitInfoDto);

                    var now = DateTime.UtcNow;

                    // Specifically add the jti (nonce), iat (issued timestamp), and sub (subject/user)
                    // claims. You can add other claims here, if you want:
                    var claims = new List <Claim>()
                    {
                        new Claim(JwtRegisteredClaimNames.Sub, username),
                        new Claim(JwtRegisteredClaimNames.Jti, await options.NonceGenerator()),
                        new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(now).ToString(), ClaimValueTypes.Integer64),
                        new Claim(ClaimTypes.UserData, roleAccessDTO.FirstOrDefault().Unit_GUID.ToString()),
                        new Claim(ClaimTypes.Name, username),
                        new Claim(ClaimTypes.PrimarySid, roleAccessDTO.FirstOrDefault().UserId.ToString()),
                        new Claim(ClaimTypes.Upn, roleAccessDTO.FirstOrDefault().UnitType.ToString())
                    };

                    roleAccessDTO.ForEach(x => claims.Add(new Claim(ClaimTypes.Role, x.FunctionName)));

                    // Create the JWT and write it to a string
                    var jwt = new JwtSecurityToken(
                        issuer: options.Issuer,
                        audience: options.Audience,
                        claims: claims,
                        notBefore: now,
                        expires: now.Add(options.Expiration),
                        signingCredentials: options.SigningCredentials);
                    var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

                    TokenDTO tokenDTO = new TokenDTO
                    {
                        AccessToken = encodedJwt,
                        ExpiresIn   = (int)options.Expiration.TotalSeconds,
                        RoleActions = roleAccessDTO,
                        UserName    = username
                    };

                    // Serialize and return the response
                    context.Response.ContentType = "application/json";
                    loggingHelper.LogMethodExit(methodName, priority, exitEventId);
                    await context.Response.WriteAsync(JsonConvert.SerializeObject(tokenDTO, serializerSettings));
                }
            }
            catch (Exception ex)
            {
                loggingHelper.Log(ErrorConstants.Err_Token, TraceEventType.Error, ex);
                var result = JsonConvert.SerializeObject(new { error = ErrorConstants.Err_Default });
                context.Response.ContentType = "application/json";
                context.Response.StatusCode  = (int)HttpStatusCode.BadRequest;
                await context.Response.WriteAsync(result);
            }
        }