예제 #1
0
    public async Task <bool> SaveAppUser(AppUser user, string newPasswordToHash = null)
    {
        bool success = true;

        if (!String.IsNullOrEmpty(newPasswordToHash))
        {
            user.PasswordSalt = PasswordHashing.PasswordSaltInBase64();
            user.PasswordHash = PasswordHashing.PasswordToHashBase64(newPasswordToHash, user.PasswordSalt);
        }
        try
        {
            using (var conn = new SqlConnection(_connectionString))
            {
                await conn.OpenAsync();

                string upsert =
                    $"MERGE [AppUser] WITH (ROWLOCK) AS [T] " +
                    $"USING (SELECT {user.Id} AS [id]) AS [S] " +
                    $"ON [T].[id] = [S].[id] " +
                    $"WHEN MATCHED THEN UPDATE SET [SubjectId]='{user.SubjectId}', [Username]='{user.Username}', [PasswordHash]='{user.PasswordHash}', [PasswordSalt]='{user.PasswordSalt}', [ProviderName]='{user.ProviderName}', [ProviderSubjectId]='{user.ProviderSubjectId}' " +
                    $"WHEN NOT MATCHED THEN INSERT ([SubjectId],[Username],[PasswordHash],[PasswordSalt],[ProviderName],[ProviderSubjectId]) " +
                    $"VALUES ('{user.SubjectId}','{user.Username}','{user.PasswordHash}','{user.PasswordSalt}','{user.ProviderName}','{user.ProviderSubjectId}'); " +
                    $"SELECT SCOPE_IDENTITY();";
                object result = null;
                using (var cmd = new SqlCommand(upsert, conn))
                {
                    result = await cmd.ExecuteScalarAsync();
                }
                int newId = (result is null || result is DBNull) ? 0 : Convert.ToInt32(result); // SCOPE_IDENTITY returns a SQL numeric(38,0) type
                if (newId > 0)
                {
                    user.Id = newId;
                }
                if (user.Id > 0 && user.Claims.Count > 0)
                {
                    foreach (Claim c in user.Claims)
                    {
                        string insertIfNew =
                            $"MERGE [Claim] AS [T] " +
                            $"USING (SELECT {user.Id} AS [uid], '{c.Subject}' AS [sub], '{c.Type}' AS [type], '{c.Value}' as [val]) AS [S] " +
                            $"ON [T].[AppUser_id]=[S].[uid] AND [T].[Subject]=[S].[sub] AND [T].[Type]=[S].[type] AND [T].[Value]=[S].[val] " +
                            $"WHEN NOT MATCHED THEN INSERT ([AppUser_id],[Issuer],[OriginalIssuer],[Subject],[Type],[Value],[ValueType]) " +
                            $"VALUES ('{user.Id}','{c.Issuer ?? string.Empty}','{c.OriginalIssuer ?? string.Empty}','{user.SubjectId}','{c.Type}','{c.Value}','{c.ValueType ?? string.Empty}');";
                        using (var cmd = new SqlCommand(insertIfNew, conn))
                        {
                            await cmd.ExecuteNonQueryAsync();
                        }
                    }
                }
            }
        }
        catch
        {
            success = false;
        }
        return(success);
    }
예제 #2
0
        private async Task <long> CreateUserAsync(AppUser user, IFormCollection form)
        {
            await setAuthorizationHeaders();

            //TODO: This needs to be moved to the so far nonexistent service layer
            string password = form["password"];
            string role     = form["role"];

            user.Claims = new List <Claim>();
            switch (role)
            {
            case ("user"):
                user.Claims.Add(new Claim(
                                    type: "role",
                                    value: "user"));
                break;

            case ("admin"):
                user.Claims.Add(new Claim(
                                    type: "role",
                                    value: "user"));
                user.Claims.Add(new Claim(
                                    type: "role",
                                    value: "admin"));
                break;

            default:
                //shouldn't get to here if there's proper validation
                throw new Exception("Something went wrong with the dropdown menu");
            }
            user.Claims.Add(new Claim(
                                type: "username",
                                value: user.Username));
            user.PasswordSalt = PasswordHashing.PasswordSaltInBase64();
            user.PasswordHash = PasswordHashing.PasswordToHashBase64(password, user.PasswordSalt);

            // TODO: Change this id generation if it behaves unexpectedly(duplicates etc)
            user.SubjectId = PasswordHashing.PasswordSaltInBase64();

            HttpResponseMessage response = await _client.PostAsJsonAsync(baseUrl, user);

            response.EnsureSuccessStatusCode();

            string[] parts = response.Headers.Location.ToString().Split("/");
            return(Convert.ToInt64(parts[parts.Length - 1]));
        }