public async Task <UserSettingsListModel> GetAllAsync(string userId)
        {
            UserSettingsInput input = new UserSettingsInput
            {
                UserId = userId,
            };

            return(await this.container.GetAllAsync(input));
        }
        public async Task <UserSettingsModel> GetAsync(string userId, string setting)
        {
            UserSettingsInput input = new UserSettingsInput
            {
                UserId     = userId,
                SettingKey = setting,
            };

            return(await this.container.GetAsync(input));
        }
        public async Task <UserSettingsModel> PutAsync(string userId, string setting, string value)
        {
            UserSettingsInput input = new UserSettingsInput
            {
                UserId     = userId,
                SettingKey = setting,
                Value      = value,
            };

            return(await this.container.UpdateAsync(input));
        }
        public async Task <UserSettingsModel> CreateUserSettings(Invitation invitation, string userId)
        {
            UserSettingsInput settingsInput = new UserSettingsInput
            {
                UserId     = userId,
                SettingKey = "InviteUserMetaData",
                Value      = invitation.InviteUserMetaData,
            };

            return(await this.userSettingsContainer.CreateAsync(settingsInput));
        }
예제 #5
0
        private async Task CleanupUserSettingsIfUserHasNoOtherTenants(UserTenantModel userTenantModel)
        {
            if (userTenantModel != null)
            {
                bool userHasOtherTenants = await this.DoesUserHaveAnyOtherTenants(userTenantModel.UserId);

                if (!userHasOtherTenants)
                {
                    UserSettingsInput settingsInput = new UserSettingsInput();
                    settingsInput.UserId = userTenantModel.UserId;
                    UserSettingsListModel userSettings = await this.settingsContainer.GetAllAsync(settingsInput);

                    if (userSettings != null && userSettings.Models != null)
                    {
                        foreach (UserSettingsModel settingsModel in userSettings.Models)
                        {
                            settingsInput.UserId     = settingsModel.UserId;
                            settingsInput.SettingKey = settingsModel.SettingKey;
                            await this.settingsContainer.DeleteAsync(settingsInput);
                        }
                    }
                }
            }
        }
예제 #6
0
        public async Task <JwtSecurityToken> GetIdentityToken(List <Claim> claims, string tenant, string audience, DateTime?expiration)
        {
            // add iat claim
            var timeSinceEpoch = DateTime.UtcNow.ToEpochTime();

            claims.Add(new Claim("iat", timeSinceEpoch.ToString(), ClaimValueTypes.Integer));

            var userId = claims.First(t => t.Type == "sub").Value;

            // Create a userTenantInput for the purpose of finding the full tenant list associated with this user
            UserTenantInput tenantInput = new UserTenantInput
            {
                UserId = userId,
            };
            UserTenantListModel tenantsModel = await this.userTenantContainer.GetAllAsync(tenantInput);

            List <UserTenantModel> tenantList = tenantsModel.Models;

            // User did not specify the tenant to log into so get the default or last used
            if (string.IsNullOrEmpty(tenant))
            {
                // authState has no tenant, so we should use either the User's last used tenant, or the first tenant available to them
                // Create a UserSettingsInput for the purpose of finding the LastUsedTenant setting for this user
                this.logger.LogInformation("User did not specify Tenant so default/last used tenant is set.");
                UserSettingsInput settingsInput = new UserSettingsInput
                {
                    UserId     = userId,
                    SettingKey = "LastUsedTenant",
                };
                UserSettingsModel lastUsedSetting = await this.userSettingsContainer.GetAsync(settingsInput);

                // Has last used tenant and it is in the list
                if (lastUsedSetting != null && tenantList.Count(t => t.TenantId == lastUsedSetting.Value) > 0)
                {
                    tenant = lastUsedSetting.Value;
                }

                if (string.IsNullOrEmpty(tenant) && tenantList.Count > 0)
                {
                    tenant =
                        tenantList.First()
                        .TenantId;     // Set the tenant to the first tenant in the list of tenants for this user
                }
            }

            // If User not associated with Tenant then dont add claims return token without
            if (tenant != null)
            {
                UserTenantInput input = new UserTenantInput
                {
                    UserId = userId,
                    Tenant = tenant,
                };
                UserTenantModel tenantModel = await this.userTenantContainer.GetAsync(input);

                // Add Tenant
                claims.Add(new Claim("tenant", tenantModel.TenantId));

                // Add Roles
                tenantModel.RoleList.ForEach(role => claims.Add(new Claim("role", role)));

                // Settings Update LastUsedTenant
                UserSettingsInput settingsInput = new UserSettingsInput
                {
                    UserId     = claims.Where(c => c.Type == "sub").First().Value,
                    SettingKey = "LastUsedTenant",
                    Value      = tenant,
                };

                // Update if name is not the same
                await this.userSettingsContainer.UpdateAsync(settingsInput);

                if (tenantModel.Name != claims.Where(c => c.Type == "name").First().Value)
                {
                    input.Name = claims.Where(c => c.Type == "name").First().Value;
                    await this.userTenantContainer.UpdateAsync(input);
                }
            }

            DateTime expirationDateTime = expiration ?? DateTime.Now.AddDays(30);

            // add all tenants they have access to
            claims.AddRange(tenantList.Select(t => new Claim("available_tenants", t.TenantId)));

            // Token to String so you can use it in your client
            var token = this.MintToken(claims, audience, expirationDateTime);

            return(token);
        }
예제 #7
0
        public async Task <object> PostAsync(
            [FromForm] string state,
            [FromForm] string id_token,
            [FromForm] string error,
            [FromForm] string error_description)
        {
            if (!string.IsNullOrEmpty(error))
            {
                // If there was an error returned from B2C, throw it as an expcetion
                throw new Exception($"Azure B2C returned an error: {{{error}: {error_description}}}");
            }

            AuthState authState = null;

            try
            {
                authState = JsonConvert.DeserializeObject <AuthState>(state);
            }
            catch (Exception e)
            {
                throw new Exception("Invlid state from authentication redirect", e);
            }

            var originalAudience = authState.ClientId;

            // Bring over Subject and Name
            var jwtHandler = new JwtSecurityTokenHandler();
            var jwt        = jwtHandler.ReadJwtToken(id_token);
            var claims     = jwt.Claims.Where(t => new List <string> {
                "sub", "name"
            }.Contains(t.Type)).ToList();
            string invitedTenant   = authState.Tenant;
            string userNameOrEmail = string.Empty;

            // If theres an invitation token then add user to tenant
            if (!string.IsNullOrEmpty(authState.Invitation))
            {
                var    inviteJWT    = jwtHandler.ReadJwtToken(authState.Invitation);
                string inviteUserId = inviteJWT.Claims.Where(c => c.Type == "userId").First().Value;
                string newUserId    = claims.Where(c => c.Type == "sub").First().Value;
                invitedTenant = inviteJWT.Claims.Where(c => c.Type == "tenant").First().Value;

                // Extract first email
                var emailClaim = jwt.Claims.Where(t => t.Type == "emails").FirstOrDefault();
                if (emailClaim != null)
                {
                    claims.Add(new Claim("email", emailClaim.Value));
                    var userName = claims.Where(c => c.Type == "name").FirstOrDefault();
                    if (userName == null)
                    {
                        // Adding the name to claims as the update name code block fails inside method GetIdentityToken in JwtHelpers
                        claims.Add(new Claim("name", emailClaim.Value));
                        userNameOrEmail = emailClaim.Value;
                    }
                    else
                    {
                        userNameOrEmail = userName.Value;
                    }
                }

                UserTenantInput userTenant = new UserTenantInput()
                {
                    UserId = newUserId,
                    Tenant = invitedTenant,
                    Roles  = JsonConvert.SerializeObject(inviteJWT.Claims.Where(c => c.Type == "role").Select(c => c.Value).ToList()),
                    Type   = "Member",
                    Name   = userNameOrEmail,
                };
                await this.userTenantContainer.UpdateAsync(userTenant);

                UserSettingsInput userSettings = new UserSettingsInput()
                {
                    UserId     = newUserId,
                    SettingKey = "inviteId",
                    Value      = inviteUserId,
                };

                // Store invite Id
                await this.userSettingsContainer.UpdateAsync(userSettings);

                // Transfer settings to new userID
                await this.userSettingsContainer.UpdateUserIdAsync(inviteUserId, newUserId);

                try
                {
                    // Delete placeholder for invite
                    userTenant.UserId = inviteUserId;
                    await this.userTenantContainer.DeleteAsync(userTenant);
                }
                catch (Exception)
                {
                    // Do nothing, delete will fail only for scenarios where the update is incorrectly working or if the invited user gets deleted for some reason.
                    // Not throwing an exception because a delete failure will not break the code however there will be some unused invites
                }
            }

            if (!string.IsNullOrEmpty(authState.Nonce))
            {
                claims.Add(new Claim("nonce", authState.Nonce));
            }

            string tokenString = jwtHandler.WriteToken(await this.jwtHelper.GetIdentityToken(claims, invitedTenant, originalAudience, null));

            // Build Return Uri
            var returnUri = new UriBuilder(authState.ReturnUrl);

            // Need to build Query carefully to not clobber other query items -- just injecting state
            // var query = HttpUtility.ParseQueryString(returnUri.Query);
            // query["state"] = HttpUtility.UrlEncode(authState.state);
            // returnUri.Query = query.ToString();
            returnUri.Fragment =
                "id_token=" + tokenString + "&state=" +
                HttpUtility.UrlEncode(authState
                                      .State); // pass token in Fragment for more security (Browser wont forward...)
            return(this.Redirect(returnUri.Uri.ToString()));
        }
 public UserSettingsModel(UserSettingsInput input)
 {
     this.PartitionKey = input.UserId;
     this.RowKey       = input.SettingKey;
     this.Value        = input.Value;
 }