From 7ca8629a136c1ba437c992052dcbfd856b5dea12 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 6 Mar 2017 20:51:13 -0500 Subject: [PATCH] org user details apis --- src/Api/Controllers/AccountsController.cs | 20 +++++++++++---- .../OrganizationUsersController.cs | 2 +- .../Response/OrganizationUserResponseModel.cs | 2 +- .../ProfileOrganizationResponseModel.cs | 22 ++++++++++++++++ .../Models/Response/ProfileResponseModel.cs | 20 ++++----------- .../OrganizationUserOrganizationDetails.cs | 13 ++++++++++ ...ails.cs => OrganizationUserUserDetails.cs} | 3 ++- .../IOrganizationUserRepository.cs | 5 ++-- .../SqlServer/OrganizationUserRepository.cs | 25 ++++++++++++++----- src/Sql/Sql.sqlproj | 8 +++--- ...onUserOrganizationDetails_ReadByUserId.sql | 13 ++++++++++ ... OrganizationUserUserDetails_ReadById.sql} | 4 +-- ...nUserUserDetails_ReadByOrganizationId.sql} | 4 +-- ...rganizationUserOrganizationDetailsView.sql | 12 +++++++++ ...ql => OrganizationUserUserDetailsView.sql} | 4 +-- 15 files changed, 117 insertions(+), 40 deletions(-) create mode 100644 src/Api/Models/Response/ProfileOrganizationResponseModel.cs create mode 100644 src/Core/Models/Data/OrganizationUserOrganizationDetails.cs rename src/Core/Models/Data/{OrganizationUserDetails.cs => OrganizationUserUserDetails.cs} (79%) create mode 100644 src/Sql/dbo/Stored Procedures/OrganizationUserOrganizationDetails_ReadByUserId.sql rename src/Sql/dbo/Stored Procedures/{OrganizationUserDetails_ReadById.sql => OrganizationUserUserDetails_ReadById.sql} (50%) rename src/Sql/dbo/Stored Procedures/{OrganizationUserDetails_ReadByOrganizationId.sql => OrganizationUserUserDetails_ReadByOrganizationId.sql} (54%) create mode 100644 src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql rename src/Sql/dbo/Views/{OrganizationUserDetailsView.sql => OrganizationUserUserDetailsView.sql} (67%) diff --git a/src/Api/Controllers/AccountsController.cs b/src/Api/Controllers/AccountsController.cs index 3492370da9..034969579d 100644 --- a/src/Api/Controllers/AccountsController.cs +++ b/src/Api/Controllers/AccountsController.cs @@ -10,6 +10,7 @@ using Bit.Core.Domains; using Bit.Core.Enums; using System.Linq; using Bit.Core.Repositories; +using System.Collections; namespace Bit.Api.Controllers { @@ -19,18 +20,18 @@ namespace Bit.Api.Controllers { private readonly IUserService _userService; private readonly ICipherService _cipherService; - private readonly IOrganizationRepository _organizationRepository; + private readonly IOrganizationUserRepository _organizationUserRepository; private readonly UserManager _userManager; public AccountsController( IUserService userService, ICipherService cipherService, - IOrganizationRepository organizationRepository, + IOrganizationUserRepository organizationUserRepository, UserManager userManager) { _userService = userService; _cipherService = cipherService; - _organizationRepository = organizationRepository; + _organizationUserRepository = organizationUserRepository; _userManager = userManager; } @@ -159,11 +160,20 @@ namespace Bit.Api.Controllers public async Task GetProfile() { var user = await _userService.GetUserByPrincipalAsync(User); - var organizations = await _organizationRepository.GetManyByUserIdAsync(user.Id); - var response = new ProfileResponseModel(user, organizations); + var organizationUserDetails = await _organizationUserRepository.GetManyDetailsByUserAsync(user.Id); + var response = new ProfileResponseModel(user, organizationUserDetails); return response; } + [HttpGet("organizations")] + public async Task> GetOrganizations() + { + var userId = _userService.GetProperUserId(User); + var organizationUserDetails = await _organizationUserRepository.GetManyDetailsByUserAsync(userId.Value); + var responseData = organizationUserDetails.Select(o => new ProfileOrganizationResponseModel(o)); + return new ListResponseModel(responseData); + } + [HttpPut("profile")] [HttpPost("profile")] public async Task PutProfile([FromBody]UpdateProfileRequestModel model) diff --git a/src/Api/Controllers/OrganizationUsersController.cs b/src/Api/Controllers/OrganizationUsersController.cs index 06cd544e08..d7cbc3446a 100644 --- a/src/Api/Controllers/OrganizationUsersController.cs +++ b/src/Api/Controllers/OrganizationUsersController.cs @@ -46,7 +46,7 @@ namespace Bit.Api.Controllers [HttpGet("")] public async Task> Get(string orgId) { - var organizationUsers = await _organizationUserRepository.GetManyDetailsByOrganizationsAsync(new Guid(orgId)); + var organizationUsers = await _organizationUserRepository.GetManyDetailsByOrganizationAsync(new Guid(orgId)); var responses = organizationUsers.Select(o => new OrganizationUserResponseModel(o)); return new ListResponseModel(responses); } diff --git a/src/Api/Models/Response/OrganizationUserResponseModel.cs b/src/Api/Models/Response/OrganizationUserResponseModel.cs index ae6e326de0..60dd16d8b4 100644 --- a/src/Api/Models/Response/OrganizationUserResponseModel.cs +++ b/src/Api/Models/Response/OrganizationUserResponseModel.cs @@ -6,7 +6,7 @@ namespace Bit.Api.Models { public class OrganizationUserResponseModel : ResponseModel { - public OrganizationUserResponseModel(OrganizationUserDetails organizationUser, string obj = "organizationUser") + public OrganizationUserResponseModel(OrganizationUserUserDetails organizationUser, string obj = "organizationUser") : base(obj) { if(organizationUser == null) diff --git a/src/Api/Models/Response/ProfileOrganizationResponseModel.cs b/src/Api/Models/Response/ProfileOrganizationResponseModel.cs new file mode 100644 index 0000000000..a433a546e7 --- /dev/null +++ b/src/Api/Models/Response/ProfileOrganizationResponseModel.cs @@ -0,0 +1,22 @@ +using Bit.Core.Enums; +using Bit.Core.Models.Data; + +namespace Bit.Api.Models +{ + public class ProfileOrganizationResponseModel : ResponseModel + { + public ProfileOrganizationResponseModel(OrganizationUserOrganizationDetails organization) + : base("profileOrganization") + { + Id = organization.OrganizationId.ToString(); + Name = organization.Name; + Key = organization.Key; + Status = organization.Status; + } + + public string Id { get; set; } + public string Name { get; set; } + public string Key { get; set; } + public OrganizationUserStatusType Status { get; set; } + } +} diff --git a/src/Api/Models/Response/ProfileResponseModel.cs b/src/Api/Models/Response/ProfileResponseModel.cs index cc4ce58364..09229ad808 100644 --- a/src/Api/Models/Response/ProfileResponseModel.cs +++ b/src/Api/Models/Response/ProfileResponseModel.cs @@ -2,12 +2,14 @@ using Bit.Core.Domains; using System.Collections.Generic; using System.Linq; +using Bit.Core.Models.Data; +using Bit.Core.Enums; namespace Bit.Api.Models { public class ProfileResponseModel : ResponseModel { - public ProfileResponseModel(User user, IEnumerable organizations) + public ProfileResponseModel(User user, IEnumerable organizationsUserDetails) : base("profile") { if(user == null) @@ -21,7 +23,7 @@ namespace Bit.Api.Models MasterPasswordHint = string.IsNullOrWhiteSpace(user.MasterPasswordHint) ? null : user.MasterPasswordHint; Culture = user.Culture; TwoFactorEnabled = user.TwoFactorEnabled; - Organizations = organizations?.Select(o => new OrganizationResponseModel(o)); + Organizations = organizationsUserDetails?.Select(o => new ProfileOrganizationResponseModel(o)); } public string Id { get; set; } @@ -30,18 +32,6 @@ namespace Bit.Api.Models public string MasterPasswordHint { get; set; } public string Culture { get; set; } public bool TwoFactorEnabled { get; set; } - public IEnumerable Organizations { get; set; } - - public class OrganizationResponseModel - { - public OrganizationResponseModel(Organization organization) - { - Id = organization.Id.ToString(); - Name = organization.Name; - } - - public string Id { get; set; } - public string Name { get; set; } - } + public IEnumerable Organizations { get; set; } } } diff --git a/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs b/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs new file mode 100644 index 0000000000..71026adace --- /dev/null +++ b/src/Core/Models/Data/OrganizationUserOrganizationDetails.cs @@ -0,0 +1,13 @@ +using System; + +namespace Bit.Core.Models.Data +{ + public class OrganizationUserOrganizationDetails + { + public Guid OrganizationId { get; set; } + public Guid? UserId { get; set; } + public string Name { get; set; } + public string Key { get; set; } + public Enums.OrganizationUserStatusType Status { get; set; } + } +} diff --git a/src/Core/Models/Data/OrganizationUserDetails.cs b/src/Core/Models/Data/OrganizationUserUserDetails.cs similarity index 79% rename from src/Core/Models/Data/OrganizationUserDetails.cs rename to src/Core/Models/Data/OrganizationUserUserDetails.cs index 478fc34b91..2e25e70511 100644 --- a/src/Core/Models/Data/OrganizationUserDetails.cs +++ b/src/Core/Models/Data/OrganizationUserUserDetails.cs @@ -2,9 +2,10 @@ namespace Bit.Core.Models.Data { - public class OrganizationUserDetails + public class OrganizationUserUserDetails { public Guid Id { get; set; } + public Guid OrganizationId { get; set; } public Guid? UserId { get; set; } public string Name { get; set; } public string Email { get; set; } diff --git a/src/Core/Repositories/IOrganizationUserRepository.cs b/src/Core/Repositories/IOrganizationUserRepository.cs index d152f6c480..0b708355bc 100644 --- a/src/Core/Repositories/IOrganizationUserRepository.cs +++ b/src/Core/Repositories/IOrganizationUserRepository.cs @@ -9,7 +9,8 @@ namespace Bit.Core.Repositories public interface IOrganizationUserRepository : IRepository { Task GetByOrganizationAsync(Guid organizationId, Guid userId); - Task GetDetailsByIdAsync(Guid id); - Task> GetManyDetailsByOrganizationsAsync(Guid organizationId); + Task GetDetailsByIdAsync(Guid id); + Task> GetManyDetailsByOrganizationAsync(Guid organizationId); + Task> GetManyDetailsByUserAsync(Guid userId); } } diff --git a/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs b/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs index a882472489..b6d6a9401d 100644 --- a/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs +++ b/src/Core/Repositories/SqlServer/OrganizationUserRepository.cs @@ -33,12 +33,12 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task GetDetailsByIdAsync(Guid id) + public async Task GetDetailsByIdAsync(Guid id) { using(var connection = new SqlConnection(ConnectionString)) { - var results = await connection.QueryAsync( - "[dbo].[OrganizationUserDetails_ReadById]", + var results = await connection.QueryAsync( + "[dbo].[OrganizationUserUserDetails_ReadById]", new { Id = id }, commandType: CommandType.StoredProcedure); @@ -46,17 +46,30 @@ namespace Bit.Core.Repositories.SqlServer } } - public async Task> GetManyDetailsByOrganizationsAsync(Guid organizationId) + public async Task> GetManyDetailsByOrganizationAsync(Guid organizationId) { using(var connection = new SqlConnection(ConnectionString)) { - var results = await connection.QueryAsync( - "[dbo].[OrganizationUserDetails_ReadByOrganizationId]", + var results = await connection.QueryAsync( + "[dbo].[OrganizationUserUserDetails_ReadByOrganizationId]", new { OrganizationId = organizationId }, commandType: CommandType.StoredProcedure); return results.ToList(); } } + + public async Task> GetManyDetailsByUserAsync(Guid userId) + { + using(var connection = new SqlConnection(ConnectionString)) + { + var results = await connection.QueryAsync( + "[dbo].[OrganizationUserOrganizationDetails_ReadByUserId]", + new { UserId = userId }, + commandType: CommandType.StoredProcedure); + + return results.ToList(); + } + } } } diff --git a/src/Sql/Sql.sqlproj b/src/Sql/Sql.sqlproj index e459acc1a0..24dcec9628 100644 --- a/src/Sql/Sql.sqlproj +++ b/src/Sql/Sql.sqlproj @@ -142,9 +142,11 @@ - - - + + + + + \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUserOrganizationDetails_ReadByUserId.sql b/src/Sql/dbo/Stored Procedures/OrganizationUserOrganizationDetails_ReadByUserId.sql new file mode 100644 index 0000000000..88d22b5900 --- /dev/null +++ b/src/Sql/dbo/Stored Procedures/OrganizationUserOrganizationDetails_ReadByUserId.sql @@ -0,0 +1,13 @@ +CREATE PROCEDURE [dbo].[OrganizationUserOrganizationDetails_ReadByUserId] + @UserId UNIQUEIDENTIFIER +AS +BEGIN + SET NOCOUNT ON + + SELECT + * + FROM + [dbo].[OrganizationUserOrganizationDetailsView] + WHERE + [UserId] = @UserId +END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUserDetails_ReadById.sql b/src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadById.sql similarity index 50% rename from src/Sql/dbo/Stored Procedures/OrganizationUserDetails_ReadById.sql rename to src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadById.sql index 3c706c22c1..97116d56a4 100644 --- a/src/Sql/dbo/Stored Procedures/OrganizationUserDetails_ReadById.sql +++ b/src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadById.sql @@ -1,4 +1,4 @@ -CREATE PROCEDURE [dbo].[OrganizationUserDetails_ReadById] +CREATE PROCEDURE [dbo].[OrganizationUserUserDetails_ReadById] @Id UNIQUEIDENTIFIER AS BEGIN @@ -7,7 +7,7 @@ BEGIN SELECT * FROM - [dbo].[OrganizationUserDetailsView] + [dbo].[OrganizationUserUserDetailsView] WHERE [Id] = @Id END \ No newline at end of file diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUserDetails_ReadByOrganizationId.sql b/src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadByOrganizationId.sql similarity index 54% rename from src/Sql/dbo/Stored Procedures/OrganizationUserDetails_ReadByOrganizationId.sql rename to src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadByOrganizationId.sql index 9f309cc79a..4d7f2ff8d2 100644 --- a/src/Sql/dbo/Stored Procedures/OrganizationUserDetails_ReadByOrganizationId.sql +++ b/src/Sql/dbo/Stored Procedures/OrganizationUserUserDetails_ReadByOrganizationId.sql @@ -1,4 +1,4 @@ -CREATE PROCEDURE [dbo].[OrganizationUserDetails_ReadByOrganizationId] +CREATE PROCEDURE [dbo].[OrganizationUserUserDetails_ReadByOrganizationId] @OrganizationId UNIQUEIDENTIFIER AS BEGIN @@ -7,7 +7,7 @@ BEGIN SELECT * FROM - [dbo].[OrganizationUserDetailsView] + [dbo].[OrganizationUserUserDetailsView] WHERE [OrganizationId] = @OrganizationId END \ No newline at end of file diff --git a/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql b/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql new file mode 100644 index 0000000000..a49cfff580 --- /dev/null +++ b/src/Sql/dbo/Views/OrganizationUserOrganizationDetailsView.sql @@ -0,0 +1,12 @@ +CREATE VIEW [dbo].[OrganizationUserOrganizationDetailsView] +AS +SELECT + OU.[UserId], + OU.[OrganizationId], + O.[Name], + OU.[Key], + OU.[Status] +FROM + [dbo].[OrganizationUser] OU +INNER JOIN + [dbo].[Organization] O ON O.[Id] = OU.[OrganizationId] \ No newline at end of file diff --git a/src/Sql/dbo/Views/OrganizationUserDetailsView.sql b/src/Sql/dbo/Views/OrganizationUserUserDetailsView.sql similarity index 67% rename from src/Sql/dbo/Views/OrganizationUserDetailsView.sql rename to src/Sql/dbo/Views/OrganizationUserUserDetailsView.sql index dec38c4ce2..c982dd2d66 100644 --- a/src/Sql/dbo/Views/OrganizationUserDetailsView.sql +++ b/src/Sql/dbo/Views/OrganizationUserUserDetailsView.sql @@ -1,4 +1,4 @@ -CREATE VIEW [dbo].[OrganizationUserDetailsView] +CREATE VIEW [dbo].[OrganizationUserUserDetailsView] AS SELECT OU.[Id], @@ -11,4 +11,4 @@ SELECT FROM [dbo].[OrganizationUser] OU LEFT JOIN - [dbo].[User] U ON U.Id = OU.UserId \ No newline at end of file + [dbo].[User] U ON U.[Id] = OU.[UserId] \ No newline at end of file