1
0
mirror of https://github.com/bitwarden/server.git synced 2025-05-23 12:31:06 -05:00

apikey apis for orgs

This commit is contained in:
Kyle Spearrin 2019-03-04 09:52:43 -05:00
parent 6922cff638
commit 42b104bc8f
5 changed files with 105 additions and 0 deletions

View File

@ -378,5 +378,72 @@ namespace Bit.Api.Controllers
model.Users.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()), model.Users.Where(u => !u.Deleted).Select(u => u.ToImportedOrganizationUser()),
model.Users.Where(u => u.Deleted).Select(u => u.ExternalId)); model.Users.Where(u => u.Deleted).Select(u => u.ExternalId));
} }
[HttpPost("{id}/api-key")]
public async Task<ApiKeyResponseModel> ApiKey(string id, [FromBody]ApiKeyRequestModel model)
{
var orgIdGuid = new Guid(id);
if(!_currentContext.OrganizationOwner(orgIdGuid))
{
throw new NotFoundException();
}
var organization = await _organizationRepository.GetByIdAsync(orgIdGuid);
if(organization == null)
{
throw new NotFoundException();
}
var user = await _userService.GetUserByPrincipalAsync(User);
if(user == null)
{
throw new UnauthorizedAccessException();
}
if(!await _userService.CheckPasswordAsync(user, model.MasterPasswordHash))
{
await Task.Delay(2000);
throw new BadRequestException("MasterPasswordHash", "Invalid password.");
}
else
{
var response = new ApiKeyResponseModel(organization);
return response;
}
}
[HttpPost("{id}/rotate-api-key")]
public async Task<ApiKeyResponseModel> RotateApiKey(string id, [FromBody]ApiKeyRequestModel model)
{
var orgIdGuid = new Guid(id);
if(!_currentContext.OrganizationOwner(orgIdGuid))
{
throw new NotFoundException();
}
var organization = await _organizationRepository.GetByIdAsync(orgIdGuid);
if(organization == null)
{
throw new NotFoundException();
}
var user = await _userService.GetUserByPrincipalAsync(User);
if(user == null)
{
throw new UnauthorizedAccessException();
}
if(!await _userService.CheckPasswordAsync(user, model.MasterPasswordHash))
{
await Task.Delay(2000);
throw new BadRequestException("MasterPasswordHash", "Invalid password.");
}
else
{
await _organizationService.RotateApiKeyAsync(organization);
var response = new ApiKeyResponseModel(organization);
return response;
}
}
} }
} }

View File

@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Models.Api
{
public class ApiKeyRequestModel
{
[Required]
public string MasterPasswordHash { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using Bit.Core.Models.Table;
namespace Bit.Core.Models.Api
{
public class ApiKeyResponseModel : ResponseModel
{
public ApiKeyResponseModel(Organization organization, string obj = "apiKey")
: base(obj)
{
if(organization == null)
{
throw new ArgumentNullException(nameof(organization));
}
ApiKey = organization.ApiKey;
}
public string ApiKey { get; set; }
}
}

View File

@ -43,5 +43,6 @@ namespace Bit.Core.Services
Task<OrganizationLicense> GenerateLicenseAsync(Organization organization, Guid installationId); Task<OrganizationLicense> GenerateLicenseAsync(Organization organization, Guid installationId);
Task ImportAsync(Guid organizationId, Guid importingUserId, IEnumerable<ImportedGroup> groups, Task ImportAsync(Guid organizationId, Guid importingUserId, IEnumerable<ImportedGroup> groups,
IEnumerable<ImportedOrganizationUser> newUsers, IEnumerable<string> removeUserExternalIds); IEnumerable<ImportedOrganizationUser> newUsers, IEnumerable<string> removeUserExternalIds);
Task RotateApiKeyAsync(Organization organization);
} }
} }

View File

@ -1341,6 +1341,13 @@ namespace Bit.Core.Services
} }
} }
public async Task RotateApiKeyAsync(Organization organization)
{
organization.ApiKey = CoreHelpers.SecureRandomString(30);
organization.RevisionDate = DateTime.UtcNow;
await ReplaceAndUpdateCache(organization);
}
private async Task UpdateUsersAsync(Group group, HashSet<string> groupUsers, private async Task UpdateUsersAsync(Group group, HashSet<string> groupUsers,
Dictionary<string, Guid> existingUsersIdDict, HashSet<Guid> existingUsers = null) Dictionary<string, Guid> existingUsersIdDict, HashSet<Guid> existingUsers = null)
{ {