1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-29 13:25:17 +01:00

org context checks in org apis. remove depr. code

This commit is contained in:
Kyle Spearrin 2017-04-05 16:13:40 -04:00
parent a474449354
commit 9a1e512020
8 changed files with 69 additions and 82 deletions

View File

@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Authorization;
using Bit.Core.Models.Api; using Bit.Core.Models.Api;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Services; using Bit.Core.Services;
using Bit.Core;
namespace Bit.Api.Controllers namespace Bit.Api.Controllers
{ {
@ -18,25 +19,27 @@ namespace Bit.Api.Controllers
private readonly IOrganizationUserRepository _organizationUserRepository; private readonly IOrganizationUserRepository _organizationUserRepository;
private readonly IOrganizationService _organizationService; private readonly IOrganizationService _organizationService;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly CurrentContext _currentContext;
public OrganizationsController( public OrganizationsController(
IOrganizationRepository organizationRepository, IOrganizationRepository organizationRepository,
IOrganizationUserRepository organizationUserRepository, IOrganizationUserRepository organizationUserRepository,
IOrganizationService organizationService, IOrganizationService organizationService,
IUserService userService) IUserService userService,
CurrentContext currentContext)
{ {
_organizationRepository = organizationRepository; _organizationRepository = organizationRepository;
_organizationUserRepository = organizationUserRepository; _organizationUserRepository = organizationUserRepository;
_organizationService = organizationService; _organizationService = organizationService;
_userService = userService; _userService = userService;
_currentContext = currentContext;
} }
[HttpGet("{id}")] [HttpGet("{id}")]
public async Task<OrganizationResponseModel> Get(string id) public async Task<OrganizationResponseModel> Get(string id)
{ {
var userId = _userService.GetProperUserId(User).Value; var organization = await _organizationRepository.GetByIdAsync(new Guid(id));
var organization = await _organizationRepository.GetByIdAsync(new Guid(id), userId); if(organization == null || !_currentContext.OrganizationAdmin(organization.Id))
if(organization == null)
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
@ -44,25 +47,6 @@ namespace Bit.Api.Controllers
return new OrganizationResponseModel(organization); return new OrganizationResponseModel(organization);
} }
[HttpGet("{id}/extended")]
public async Task<OrganizationExtendedResponseModel> GetExtended(string id)
{
var userId = _userService.GetProperUserId(User).Value;
var organization = await _organizationRepository.GetByIdAsync(new Guid(id), userId);
if(organization == null)
{
throw new NotFoundException();
}
var organizationUser = await _organizationUserRepository.GetByOrganizationAsync(new Guid(id), userId);
if(organizationUser == null)
{
throw new NotFoundException();
}
return new OrganizationExtendedResponseModel(organization, organizationUser);
}
[HttpGet("")] [HttpGet("")]
public async Task<ListResponseModel<OrganizationResponseModel>> Get() public async Task<ListResponseModel<OrganizationResponseModel>> Get()
{ {
@ -73,22 +57,20 @@ namespace Bit.Api.Controllers
} }
[HttpPost("")] [HttpPost("")]
public async Task<OrganizationExtendedResponseModel> Post([FromBody]OrganizationCreateRequestModel model) public async Task<OrganizationResponseModel> Post([FromBody]OrganizationCreateRequestModel model)
{ {
var user = await _userService.GetUserByPrincipalAsync(User); var user = await _userService.GetUserByPrincipalAsync(User);
var organizationSignup = model.ToOrganizationSignup(user); var organizationSignup = model.ToOrganizationSignup(user);
var result = await _organizationService.SignUpAsync(organizationSignup); var result = await _organizationService.SignUpAsync(organizationSignup);
return new OrganizationExtendedResponseModel(result.Item1, result.Item2); return new OrganizationResponseModel(result.Item1);
} }
[HttpPut("{id}")] [HttpPut("{id}")]
[HttpPost("{id}")] [HttpPost("{id}")]
public async Task<OrganizationResponseModel> Put(string id, [FromBody]OrganizationUpdateRequestModel model) public async Task<OrganizationResponseModel> Put(string id, [FromBody]OrganizationUpdateRequestModel model)
{ {
var userId = _userService.GetProperUserId(User).Value; var organization = await _organizationRepository.GetByIdAsync(new Guid(id));
var organization = await _organizationRepository.GetByIdAsync(new Guid(id), userId); if(organization == null || !_currentContext.OrganizationAdmin(organization.Id))
// TODO: Permission checks
if(organization == null)
{ {
throw new NotFoundException(); throw new NotFoundException();
} }
@ -101,9 +83,8 @@ namespace Bit.Api.Controllers
[HttpPost("{id}/delete")] [HttpPost("{id}/delete")]
public async Task Delete(string id) public async Task Delete(string id)
{ {
var organization = await _organizationRepository.GetByIdAsync(new Guid(id), var organization = await _organizationRepository.GetByIdAsync(new Guid(id));
_userService.GetProperUserId(User).Value); if(organization == null || !_currentContext.OrganizationAdmin(organization.Id))
if(organization == null)
{ {
throw new NotFoundException(); throw new NotFoundException();
} }

View File

@ -20,6 +20,39 @@ namespace Bit.Api.Middleware
{ {
var securityStampClaim = httpContext.User.Claims.FirstOrDefault(c => c.Type == "device"); var securityStampClaim = httpContext.User.Claims.FirstOrDefault(c => c.Type == "device");
currentContext.DeviceIdentifier = securityStampClaim?.Value; currentContext.DeviceIdentifier = securityStampClaim?.Value;
var orgOwnerClaims = httpContext.User.Claims.Where(c => c.Type == "orgowner");
if(orgOwnerClaims.Any())
{
currentContext.Organizations.AddRange(orgOwnerClaims.Select(c =>
new CurrentContext.CurrentContentOrganization
{
Id = new System.Guid(c.Value),
Type = Core.Enums.OrganizationUserType.Owner
}));
}
var orgAdminClaims = httpContext.User.Claims.Where(c => c.Type == "orgadmin");
if(orgAdminClaims.Any())
{
currentContext.Organizations.AddRange(orgAdminClaims.Select(c =>
new CurrentContext.CurrentContentOrganization
{
Id = new System.Guid(c.Value),
Type = Core.Enums.OrganizationUserType.Admin
}));
}
var orgUserClaims = httpContext.User.Claims.Where(c => c.Type == "orguser");
if(orgUserClaims.Any())
{
currentContext.Organizations.AddRange(orgUserClaims.Select(c =>
new CurrentContext.CurrentContentOrganization
{
Id = new System.Guid(c.Value),
Type = Core.Enums.OrganizationUserType.User
}));
}
} }
if(currentContext.DeviceIdentifier == null && httpContext.Request.Headers.ContainsKey("Device-Identifier")) if(currentContext.DeviceIdentifier == null && httpContext.Request.Headers.ContainsKey("Device-Identifier"))

View File

@ -1,8 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Bit.Core.Models.Table; using Bit.Core.Models.Table;
using Bit.Core.Enums;
namespace Bit.Core namespace Bit.Core
{ {
@ -10,5 +10,26 @@ namespace Bit.Core
{ {
public virtual User User { get; set; } public virtual User User { get; set; }
public virtual string DeviceIdentifier { get; set; } public virtual string DeviceIdentifier { get; set; }
public virtual List<CurrentContentOrganization> Organizations { get; set; } = new List<CurrentContentOrganization>();
public bool OrganizationUser(Guid orgId)
{
return Organizations.Any(o => o.Id == orgId);
}
public bool OrganizationAdmin(Guid orgId)
{
return Organizations.Any(o => o.Id == orgId &&
(o.Type == OrganizationUserType.Owner || o.Type == OrganizationUserType.Admin));
}
public bool OrganizationOwner(Guid orgId)
{
return Organizations.Any(o => o.Id == orgId && o.Type == OrganizationUserType.Owner);
}
public class CurrentContentOrganization
{
public Guid Id { get; set; }
public OrganizationUserType Type { get; set; }
}
} }
} }

View File

@ -24,24 +24,8 @@ namespace Bit.Core.Models.Api
public string Id { get; set; } public string Id { get; set; }
public string Name { get; set; } public string Name { get; set; }
public string Plan { get; set; } public string Plan { get; set; }
public Core.Enums.PlanType PlanType { get; set; } public Enums.PlanType PlanType { get; set; }
public bool PlanTrial { get; set; } public bool PlanTrial { get; set; }
public short MaxUsers { get; set; } public short MaxUsers { get; set; }
} }
public class OrganizationExtendedResponseModel : OrganizationResponseModel
{
public OrganizationExtendedResponseModel(Organization organization, OrganizationUser organizationUser)
: base(organization, "organizationExtended")
{
if(organizationUser == null)
{
throw new ArgumentNullException(nameof(organizationUser));
}
Key = organizationUser.Key;
}
public string Key { get; set; }
}
} }

View File

@ -7,7 +7,6 @@ namespace Bit.Core.Repositories
{ {
public interface IOrganizationRepository : IRepository<Organization, Guid> public interface IOrganizationRepository : IRepository<Organization, Guid>
{ {
Task<Organization> GetByIdAsync(Guid id, Guid userId);
Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId); Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId);
} }
} }

View File

@ -19,19 +19,6 @@ namespace Bit.Core.Repositories.SqlServer
: base(connectionString) : base(connectionString)
{ } { }
public async Task<Organization> GetByIdAsync(Guid id, Guid userId)
{
using(var connection = new SqlConnection(ConnectionString))
{
var results = await connection.QueryAsync<Organization>(
"[dbo].[Organization_ReadByIdUserId]",
new { Id = id, UserId = userId },
commandType: CommandType.StoredProcedure);
return results.SingleOrDefault();
}
}
public async Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId) public async Task<ICollection<Organization>> GetManyByUserIdAsync(Guid userId)
{ {
using(var connection = new SqlConnection(ConnectionString)) using(var connection = new SqlConnection(ConnectionString))

View File

@ -163,7 +163,6 @@
<Build Include="dbo\Stored Procedures\Cipher_UpdatePartial.sql" /> <Build Include="dbo\Stored Procedures\Cipher_UpdatePartial.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUserOrganizationDetails_ReadByUserIdStatus.sql" /> <Build Include="dbo\Stored Procedures\OrganizationUserOrganizationDetails_ReadByUserIdStatus.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdEmail.sql" /> <Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdEmail.sql" />
<Build Include="dbo\Stored Procedures\Organization_ReadByIdUserId.sql" />
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationId.sql" /> <Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationId.sql" />
<Build Include="dbo\Stored Procedures\Organization_ReadByUserId.sql" /> <Build Include="dbo\Stored Procedures\Organization_ReadByUserId.sql" />
<Build Include="dbo\Stored Procedures\Subvault_ReadByIdAdminUserId.sql" /> <Build Include="dbo\Stored Procedures\Subvault_ReadByIdAdminUserId.sql" />

View File

@ -1,17 +0,0 @@
CREATE PROCEDURE [dbo].[Organization_ReadByIdUserId]
@Id UNIQUEIDENTIFIER,
@UserId UNIQUEIDENTIFIER
AS
BEGIN
SET NOCOUNT ON
SELECT
O.*
FROM
[dbo].[OrganizationView] O
INNER JOIN
[dbo].[OrganizationUser] OU ON O.[Id] = OU.[OrganizationId]
WHERE
O.[Id] = @Id
AND OU.[UserId] = @UserId
END