mirror of
https://github.com/bitwarden/server.git
synced 2024-11-28 13:15:12 +01:00
upgrade identity server 4 to v4 (#842)
* upgrade identity server 4 to v4 * remove script ref
This commit is contained in:
parent
22eb8316f2
commit
623cd36bd4
@ -46,7 +46,7 @@
|
|||||||
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
|
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.AzureDocumentDB" Version="3.8.0" />
|
<PackageReference Include="Serilog.Sinks.AzureDocumentDB" Version="3.8.0" />
|
||||||
<PackageReference Include="Sentry.Serilog" Version="2.1.5" />
|
<PackageReference Include="Sentry.Serilog" Version="2.1.5" />
|
||||||
<PackageReference Include="IdentityServer4" Version="3.1.3" />
|
<PackageReference Include="IdentityServer4" Version="4.0.4" />
|
||||||
<PackageReference Include="Dapper" Version="2.0.35" />
|
<PackageReference Include="Dapper" Version="2.0.35" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="1.0.5" />
|
<PackageReference Include="Serilog.Sinks.SyslogMessages" Version="1.0.5" />
|
||||||
|
20
src/Core/IdentityServer/ApiScopes.cs
Normal file
20
src/Core/IdentityServer/ApiScopes.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using IdentityServer4.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Bit.Core.IdentityServer
|
||||||
|
{
|
||||||
|
public class ApiScopes
|
||||||
|
{
|
||||||
|
public static IEnumerable<ApiScope> GetApiScopes()
|
||||||
|
{
|
||||||
|
return new List<ApiScope>
|
||||||
|
{
|
||||||
|
new ApiScope("api", "API Access"),
|
||||||
|
new ApiScope("api.push", "API Push Access"),
|
||||||
|
new ApiScope("api.licensing", "API Licensing Access"),
|
||||||
|
new ApiScope("api.organization", "API Organization Access"),
|
||||||
|
new ApiScope("internal", "Internal Access")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,8 @@ namespace Bit.Core.IdentityServer
|
|||||||
|
|
||||||
public Task<string> StoreAuthorizationCodeAsync(AuthorizationCode code)
|
public Task<string> StoreAuthorizationCodeAsync(AuthorizationCode code)
|
||||||
{
|
{
|
||||||
return CreateItemAsync(code, code.ClientId, code.Subject.GetSubjectId(), code.CreationTime, code.Lifetime);
|
return CreateItemAsync(code, code.ClientId, code.Subject.GetSubjectId(), code.SessionId,
|
||||||
|
code.Description, code.CreationTime, code.Lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<AuthorizationCode> GetAuthorizationCodeAsync(string code)
|
public Task<AuthorizationCode> GetAuthorizationCodeAsync(string code)
|
||||||
|
@ -47,7 +47,7 @@ namespace Bit.Core.IdentityServer
|
|||||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||||
AccessTokenLifetime = 3600 * 24,
|
AccessTokenLifetime = 3600 * 24,
|
||||||
Enabled = installation.Enabled,
|
Enabled = installation.Enabled,
|
||||||
Claims = new List<Claim> { new Claim(JwtClaimTypes.Subject, installation.Id.ToString()) }
|
Claims = new List<ClientClaim> { new ClientClaim(JwtClaimTypes.Subject, installation.Id.ToString()) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ namespace Bit.Core.IdentityServer
|
|||||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||||
AccessTokenLifetime = 3600 * 24,
|
AccessTokenLifetime = 3600 * 24,
|
||||||
Enabled = true,
|
Enabled = true,
|
||||||
Claims = new List<Claim> { new Claim(JwtClaimTypes.Subject, id) }
|
Claims = new List<ClientClaim> { new ClientClaim(JwtClaimTypes.Subject, id) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ namespace Bit.Core.IdentityServer
|
|||||||
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
AllowedGrantTypes = GrantTypes.ClientCredentials,
|
||||||
AccessTokenLifetime = 3600 * 1,
|
AccessTokenLifetime = 3600 * 1,
|
||||||
Enabled = org.Enabled && org.UseApi,
|
Enabled = org.Enabled && org.UseApi,
|
||||||
Claims = new List<Claim> { new Claim(JwtClaimTypes.Subject, org.Id.ToString()) }
|
Claims = new List<ClientClaim> { new ClientClaim(JwtClaimTypes.Subject, org.Id.ToString()) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Bit.Core.Models.Table;
|
|
||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using IdentityServer4.Stores;
|
using IdentityServer4.Stores;
|
||||||
@ -19,13 +17,6 @@ namespace Bit.Core.IdentityServer
|
|||||||
_grantRepository = grantRepository;
|
_grantRepository = grantRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<PersistedGrant>> GetAllAsync(string subjectId)
|
|
||||||
{
|
|
||||||
var grants = await _grantRepository.GetManyAsync(subjectId);
|
|
||||||
var pGrants = grants.Select(g => ToPersistedGrant(g));
|
|
||||||
return pGrants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<PersistedGrant> GetAsync(string key)
|
public async Task<PersistedGrant> GetAsync(string key)
|
||||||
{
|
{
|
||||||
var grant = await _grantRepository.GetByKeyAsync(key);
|
var grant = await _grantRepository.GetByKeyAsync(key);
|
||||||
@ -38,19 +29,22 @@ namespace Bit.Core.IdentityServer
|
|||||||
return pGrant;
|
return pGrant;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RemoveAllAsync(string subjectId, string clientId)
|
public async Task<IEnumerable<PersistedGrant>> GetAllAsync(PersistedGrantFilter filter)
|
||||||
{
|
{
|
||||||
await _grantRepository.DeleteAsync(subjectId, clientId);
|
var grants = await _grantRepository.GetManyAsync(filter.SubjectId, filter.SessionId,
|
||||||
|
filter.ClientId, filter.Type);
|
||||||
|
var pGrants = grants.Select(g => ToPersistedGrant(g));
|
||||||
|
return pGrants;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RemoveAllAsync(string subjectId, string clientId, string type)
|
public async Task RemoveAllAsync(PersistedGrantFilter filter)
|
||||||
{
|
{
|
||||||
await _grantRepository.DeleteAsync(subjectId, clientId, type);
|
await _grantRepository.DeleteManyAsync(filter.SubjectId, filter.SessionId, filter.ClientId, filter.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RemoveAsync(string key)
|
public async Task RemoveAsync(string key)
|
||||||
{
|
{
|
||||||
await _grantRepository.DeleteAsync(key);
|
await _grantRepository.DeleteByKeyAsync(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StoreAsync(PersistedGrant pGrant)
|
public async Task StoreAsync(PersistedGrant pGrant)
|
||||||
@ -59,30 +53,36 @@ namespace Bit.Core.IdentityServer
|
|||||||
await _grantRepository.SaveAsync(grant);
|
await _grantRepository.SaveAsync(grant);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Grant ToGrant(PersistedGrant pGrant)
|
private Models.Table.Grant ToGrant(PersistedGrant pGrant)
|
||||||
{
|
{
|
||||||
return new Grant
|
return new Models.Table.Grant
|
||||||
{
|
{
|
||||||
Key = pGrant.Key,
|
Key = pGrant.Key,
|
||||||
Type = pGrant.Type,
|
Type = pGrant.Type,
|
||||||
SubjectId = pGrant.SubjectId,
|
SubjectId = pGrant.SubjectId,
|
||||||
|
SessionId = pGrant.SessionId,
|
||||||
ClientId = pGrant.ClientId,
|
ClientId = pGrant.ClientId,
|
||||||
|
Description = pGrant.Description,
|
||||||
CreationDate = pGrant.CreationTime,
|
CreationDate = pGrant.CreationTime,
|
||||||
ExpirationDate = pGrant.Expiration,
|
ExpirationDate = pGrant.Expiration,
|
||||||
|
ConsumedDate = pGrant.ConsumedTime,
|
||||||
Data = pGrant.Data
|
Data = pGrant.Data
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private PersistedGrant ToPersistedGrant(Grant grant)
|
private PersistedGrant ToPersistedGrant(Models.Table.Grant grant)
|
||||||
{
|
{
|
||||||
return new PersistedGrant
|
return new PersistedGrant
|
||||||
{
|
{
|
||||||
Key = grant.Key,
|
Key = grant.Key,
|
||||||
Type = grant.Type,
|
Type = grant.Type,
|
||||||
SubjectId = grant.SubjectId,
|
SubjectId = grant.SubjectId,
|
||||||
|
SessionId = grant.SessionId,
|
||||||
ClientId = grant.ClientId,
|
ClientId = grant.ClientId,
|
||||||
|
Description = grant.Description,
|
||||||
CreationTime = grant.CreationDate,
|
CreationTime = grant.CreationDate,
|
||||||
Expiration = grant.ExpirationDate,
|
Expiration = grant.ExpirationDate,
|
||||||
|
ConsumedTime = grant.ConsumedDate,
|
||||||
Data = grant.Data
|
Data = grant.Data
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,19 +14,16 @@ namespace Bit.Core.IdentityServer
|
|||||||
public class ProfileService : IProfileService
|
public class ProfileService : IProfileService
|
||||||
{
|
{
|
||||||
private readonly IUserService _userService;
|
private readonly IUserService _userService;
|
||||||
private readonly IUserRepository _userRepository;
|
|
||||||
private readonly IOrganizationUserRepository _organizationUserRepository;
|
private readonly IOrganizationUserRepository _organizationUserRepository;
|
||||||
private readonly ILicensingService _licensingService;
|
private readonly ILicensingService _licensingService;
|
||||||
private readonly CurrentContext _currentContext;
|
private readonly CurrentContext _currentContext;
|
||||||
|
|
||||||
public ProfileService(
|
public ProfileService(
|
||||||
IUserRepository userRepository,
|
|
||||||
IUserService userService,
|
IUserService userService,
|
||||||
IOrganizationUserRepository organizationUserRepository,
|
IOrganizationUserRepository organizationUserRepository,
|
||||||
ILicensingService licensingService,
|
ILicensingService licensingService,
|
||||||
CurrentContext currentContext)
|
CurrentContext currentContext)
|
||||||
{
|
{
|
||||||
_userRepository = userRepository;
|
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
_organizationUserRepository = organizationUserRepository;
|
_organizationUserRepository = organizationUserRepository;
|
||||||
_licensingService = licensingService;
|
_licensingService = licensingService;
|
||||||
@ -46,7 +43,8 @@ namespace Bit.Core.IdentityServer
|
|||||||
{
|
{
|
||||||
new Claim("premium", isPremium ? "true" : "false", ClaimValueTypes.Boolean),
|
new Claim("premium", isPremium ? "true" : "false", ClaimValueTypes.Boolean),
|
||||||
new Claim(JwtClaimTypes.Email, user.Email),
|
new Claim(JwtClaimTypes.Email, user.Email),
|
||||||
new Claim(JwtClaimTypes.EmailVerified, user.EmailVerified ? "true" : "false", ClaimValueTypes.Boolean),
|
new Claim(JwtClaimTypes.EmailVerified, user.EmailVerified ? "true" : "false",
|
||||||
|
ClaimValueTypes.Boolean),
|
||||||
new Claim("sstamp", user.SecurityStamp)
|
new Claim("sstamp", user.SecurityStamp)
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -96,13 +94,14 @@ namespace Bit.Core.IdentityServer
|
|||||||
|
|
||||||
// filter out any of the new claims
|
// filter out any of the new claims
|
||||||
var existingClaimsToKeep = existingClaims
|
var existingClaimsToKeep = existingClaims
|
||||||
.Where(c => !c.Type.StartsWith("org") && (newClaims.Count == 0 || !newClaims.Any(nc => nc.Type == c.Type)))
|
.Where(c => !c.Type.StartsWith("org") &&
|
||||||
|
(newClaims.Count == 0 || !newClaims.Any(nc => nc.Type == c.Type)))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
newClaims.AddRange(existingClaimsToKeep);
|
newClaims.AddRange(existingClaimsToKeep);
|
||||||
if (newClaims.Any())
|
if (newClaims.Any())
|
||||||
{
|
{
|
||||||
context.AddRequestedClaims(newClaims);
|
context.IssuedClaims.AddRange(newClaims);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,12 @@ namespace Bit.Core.Models.Table
|
|||||||
public string Key { get; set; }
|
public string Key { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public string SubjectId { get; set; }
|
public string SubjectId { get; set; }
|
||||||
|
public string SessionId { get; set; }
|
||||||
public string ClientId { get; set; }
|
public string ClientId { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
public DateTime CreationDate { get; set; }
|
public DateTime CreationDate { get; set; }
|
||||||
public DateTime? ExpirationDate { get; set; }
|
public DateTime? ExpirationDate { get; set; }
|
||||||
|
public DateTime? ConsumedDate { get; set; }
|
||||||
public string Data { get; set; }
|
public string Data { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,9 @@ namespace Bit.Core.Repositories
|
|||||||
public interface IGrantRepository
|
public interface IGrantRepository
|
||||||
{
|
{
|
||||||
Task<Grant> GetByKeyAsync(string key);
|
Task<Grant> GetByKeyAsync(string key);
|
||||||
Task<ICollection<Grant>> GetManyAsync(string subjectId);
|
Task<ICollection<Grant>> GetManyAsync(string subjectId, string sessionId, string clientId, string type);
|
||||||
Task SaveAsync(Grant obj);
|
Task SaveAsync(Grant obj);
|
||||||
Task DeleteAsync(string key);
|
Task DeleteByKeyAsync(string key);
|
||||||
Task DeleteAsync(string subjectId, string clientId);
|
Task DeleteManyAsync(string subjectId, string sessionId, string clientId, string type);
|
||||||
Task DeleteAsync(string subjectId, string clientId, string type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Data.SqlClient;
|
using System.Data.SqlClient;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -32,13 +31,14 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ICollection<Grant>> GetManyAsync(string subjectId)
|
public async Task<ICollection<Grant>> GetManyAsync(string subjectId, string sessionId,
|
||||||
|
string clientId, string type)
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
{
|
{
|
||||||
var results = await connection.QueryAsync<Grant>(
|
var results = await connection.QueryAsync<Grant>(
|
||||||
"[dbo].[Grant_ReadBySubjectId]",
|
"[dbo].[Grant_Read]",
|
||||||
new { SubjectId = subjectId },
|
new { SubjectId = subjectId, SessionId = sessionId, ClientId = clientId, Type = type },
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
|
|
||||||
return results.ToList();
|
return results.ToList();
|
||||||
@ -56,7 +56,7 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteAsync(string key)
|
public async Task DeleteByKeyAsync(string key)
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
{
|
{
|
||||||
@ -67,24 +67,13 @@ namespace Bit.Core.Repositories.SqlServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteAsync(string subjectId, string clientId)
|
public async Task DeleteManyAsync(string subjectId, string sessionId, string clientId, string type)
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
using (var connection = new SqlConnection(ConnectionString))
|
||||||
{
|
{
|
||||||
await connection.ExecuteAsync(
|
await connection.ExecuteAsync(
|
||||||
"[dbo].[Grant_DeleteBySubjectIdClientId]",
|
"[dbo].[Grant_Delete]",
|
||||||
new { SubjectId = subjectId, ClientId = clientId },
|
new { SubjectId = subjectId, SessionId = sessionId, ClientId = clientId, Type = type },
|
||||||
commandType: CommandType.StoredProcedure);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteAsync(string subjectId, string clientId, string type)
|
|
||||||
{
|
|
||||||
using (var connection = new SqlConnection(ConnectionString))
|
|
||||||
{
|
|
||||||
await connection.ExecuteAsync(
|
|
||||||
"[dbo].[Grant_DeleteBySubjectIdClientIdType]",
|
|
||||||
new { SubjectId = subjectId, ClientId = clientId, Type = type },
|
|
||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using Bit.Core.Models.Table;
|
|||||||
using Bit.Core.Repositories;
|
using Bit.Core.Repositories;
|
||||||
using Bit.Identity.Models;
|
using Bit.Identity.Models;
|
||||||
using IdentityModel;
|
using IdentityModel;
|
||||||
|
using IdentityServer4;
|
||||||
using IdentityServer4.Services;
|
using IdentityServer4.Services;
|
||||||
using IdentityServer4.Stores;
|
using IdentityServer4.Stores;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
@ -132,8 +133,12 @@ namespace Bit.Identity.Controllers
|
|||||||
ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps);
|
ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps);
|
||||||
|
|
||||||
// issue authentication cookie for user
|
// issue authentication cookie for user
|
||||||
await HttpContext.SignInAsync(user.Id.ToString(), user.Email, provider,
|
await HttpContext.SignInAsync(new IdentityServerUser(user.Id.ToString())
|
||||||
localSignInProps, additionalLocalClaims.ToArray());
|
{
|
||||||
|
DisplayName = user.Email,
|
||||||
|
IdentityProvider = provider,
|
||||||
|
AdditionalClaims = additionalLocalClaims.ToArray()
|
||||||
|
}, localSignInProps);
|
||||||
|
|
||||||
// delete temporary cookie used during external authentication
|
// delete temporary cookie used during external authentication
|
||||||
await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
|
await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);
|
||||||
@ -144,7 +149,7 @@ namespace Bit.Identity.Controllers
|
|||||||
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
|
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
|
||||||
if (context != null)
|
if (context != null)
|
||||||
{
|
{
|
||||||
if (await IsPkceClientAsync(context.ClientId))
|
if (await IsPkceClientAsync(context.Client.ClientId))
|
||||||
{
|
{
|
||||||
// if the client is PKCE then we assume it's native, so this change in how to
|
// if the client is PKCE then we assume it's native, so this change in how to
|
||||||
// return the response is for better UX for the end user.
|
// return the response is for better UX for the end user.
|
||||||
|
@ -65,6 +65,19 @@ namespace Bit.Identity
|
|||||||
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
|
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cookies
|
||||||
|
if (Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
services.Configure<CookiePolicyOptions>(options =>
|
||||||
|
{
|
||||||
|
options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified;
|
||||||
|
options.OnAppendCookie = ctx =>
|
||||||
|
{
|
||||||
|
ctx.CookieOptions.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
|
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
@ -133,6 +146,12 @@ namespace Bit.Identity
|
|||||||
app.UseForwardedHeaders(globalSettings);
|
app.UseForwardedHeaders(globalSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
app.UseCookiePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
// Add static files to the request pipeline.
|
// Add static files to the request pipeline.
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
|
|
||||||
@ -172,9 +191,14 @@ namespace Bit.Identity
|
|||||||
options.Endpoints.EnableTokenRevocationEndpoint = false;
|
options.Endpoints.EnableTokenRevocationEndpoint = false;
|
||||||
options.IssuerUri = $"{issuerUri.Scheme}://{issuerUri.Host}";
|
options.IssuerUri = $"{issuerUri.Scheme}://{issuerUri.Host}";
|
||||||
options.Caching.ClientStoreExpiration = new TimeSpan(0, 5, 0);
|
options.Caching.ClientStoreExpiration = new TimeSpan(0, 5, 0);
|
||||||
|
if(env.IsDevelopment())
|
||||||
|
{
|
||||||
|
options.Authentication.CookieSameSiteMode = Microsoft.AspNetCore.Http.SameSiteMode.Unspecified;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.AddInMemoryCaching()
|
.AddInMemoryCaching()
|
||||||
.AddInMemoryApiResources(ApiResources.GetApiResources())
|
.AddInMemoryApiResources(ApiResources.GetApiResources())
|
||||||
|
.AddInMemoryApiScopes(ApiScopes.GetApiScopes())
|
||||||
.AddClientStoreCache<ClientStore>()
|
.AddClientStoreCache<ClientStore>()
|
||||||
.AddCustomTokenRequestValidator<CustomTokenRequestValidator>()
|
.AddCustomTokenRequestValidator<CustomTokenRequestValidator>()
|
||||||
.AddProfileService<ProfileService>()
|
.AddProfileService<ProfileService>()
|
||||||
|
@ -109,12 +109,11 @@
|
|||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_Create.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_Create.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Grant_DeleteByKey.sql" />
|
<Build Include="dbo\Stored Procedures\Grant_DeleteByKey.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_DeleteById.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_DeleteById.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Grant_DeleteBySubjectIdClientId.sql" />
|
<Build Include="dbo\Stored Procedures\Grant_Delete.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadById.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadById.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Grant_DeleteBySubjectIdClientIdType.sql" />
|
|
||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationId.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Grant_ReadByKey.sql" />
|
<Build Include="dbo\Stored Procedures\Grant_ReadByKey.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Grant_ReadBySubjectId.sql" />
|
<Build Include="dbo\Stored Procedures\Grant_Read.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdUserId.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByOrganizationIdUserId.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\Grant_Save.sql" />
|
<Build Include="dbo\Stored Procedures\Grant_Save.sql" />
|
||||||
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByUserId.sql" />
|
<Build Include="dbo\Stored Procedures\OrganizationUser_ReadByUserId.sql" />
|
||||||
|
18
src/Sql/dbo/Stored Procedures/Grant_Delete.sql
Normal file
18
src/Sql/dbo/Stored Procedures/Grant_Delete.sql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[Grant_Delete]
|
||||||
|
@SubjectId NVARCHAR(200),
|
||||||
|
@SessionId NVARCHAR(100),
|
||||||
|
@ClientId NVARCHAR(200),
|
||||||
|
@Type NVARCHAR(50)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
DELETE
|
||||||
|
FROM
|
||||||
|
[dbo].[Grant]
|
||||||
|
WHERE
|
||||||
|
(@SubjectId IS NULL OR [SubjectId] = @SubjectId)
|
||||||
|
AND (@ClientId IS NULL OR [ClientId] = @ClientId)
|
||||||
|
AND (@SessionId IS NULL OR [SessionId] = @SessionId)
|
||||||
|
AND (@Type IS NULL OR [Type] = @Type)
|
||||||
|
END
|
@ -1,14 +0,0 @@
|
|||||||
CREATE PROCEDURE [dbo].[Grant_DeleteBySubjectIdClientId]
|
|
||||||
@SubjectId NVARCHAR(50),
|
|
||||||
@ClientId NVARCHAR(50)
|
|
||||||
AS
|
|
||||||
BEGIN
|
|
||||||
SET NOCOUNT ON
|
|
||||||
|
|
||||||
DELETE
|
|
||||||
FROM
|
|
||||||
[dbo].[Grant]
|
|
||||||
WHERE
|
|
||||||
[SubjectId] = @SubjectId
|
|
||||||
AND [ClientId] = @ClientId
|
|
||||||
END
|
|
@ -1,16 +0,0 @@
|
|||||||
CREATE PROCEDURE [dbo].[Grant_DeleteBySubjectIdClientIdType]
|
|
||||||
@SubjectId NVARCHAR(50),
|
|
||||||
@ClientId NVARCHAR(50),
|
|
||||||
@Type NVARCHAR(50)
|
|
||||||
AS
|
|
||||||
BEGIN
|
|
||||||
SET NOCOUNT ON
|
|
||||||
|
|
||||||
DELETE
|
|
||||||
FROM
|
|
||||||
[dbo].[Grant]
|
|
||||||
WHERE
|
|
||||||
[SubjectId] = @SubjectId
|
|
||||||
AND [ClientId] = @ClientId
|
|
||||||
AND [Type] = @Type
|
|
||||||
END
|
|
19
src/Sql/dbo/Stored Procedures/Grant_Read.sql
Normal file
19
src/Sql/dbo/Stored Procedures/Grant_Read.sql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
CREATE PROCEDURE [dbo].[Grant_Read]
|
||||||
|
@SubjectId NVARCHAR(200),
|
||||||
|
@SessionId NVARCHAR(100),
|
||||||
|
@ClientId NVARCHAR(200),
|
||||||
|
@Type NVARCHAR(50)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[GrantView]
|
||||||
|
WHERE
|
||||||
|
(@SubjectId IS NULL OR [SubjectId] = @SubjectId)
|
||||||
|
AND (@ClientId IS NULL OR [ClientId] = @ClientId)
|
||||||
|
AND (@SessionId IS NULL OR [SessionId] = @SessionId)
|
||||||
|
AND (@Type IS NULL OR [Type] = @Type)
|
||||||
|
END
|
@ -1,13 +0,0 @@
|
|||||||
CREATE PROCEDURE [dbo].[Grant_ReadBySubjectId]
|
|
||||||
@SubjectId NVARCHAR(50)
|
|
||||||
AS
|
|
||||||
BEGIN
|
|
||||||
SET NOCOUNT ON
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
*
|
|
||||||
FROM
|
|
||||||
[dbo].[GrantView]
|
|
||||||
WHERE
|
|
||||||
[SubjectId] = @SubjectId
|
|
||||||
END
|
|
@ -1,10 +1,13 @@
|
|||||||
CREATE PROCEDURE [dbo].[Grant_Save]
|
CREATE PROCEDURE [dbo].[Grant_Save]
|
||||||
@Key NVARCHAR(200),
|
@Key NVARCHAR(200),
|
||||||
@Type NVARCHAR(50),
|
@Type NVARCHAR(50),
|
||||||
@SubjectId NVARCHAR(50),
|
@SubjectId NVARCHAR(200),
|
||||||
@ClientId NVARCHAR(50),
|
@SessionId NVARCHAR(100),
|
||||||
|
@ClientId NVARCHAR(200),
|
||||||
|
@Description NVARCHAR(200),
|
||||||
@CreationDate DATETIME2,
|
@CreationDate DATETIME2,
|
||||||
@ExpirationDate DATETIME2,
|
@ExpirationDate DATETIME2,
|
||||||
|
@ConsumedDate DATETIME2,
|
||||||
@Data NVARCHAR(MAX)
|
@Data NVARCHAR(MAX)
|
||||||
AS
|
AS
|
||||||
BEGIN
|
BEGIN
|
||||||
@ -19,9 +22,12 @@ BEGIN
|
|||||||
@Key,
|
@Key,
|
||||||
@Type,
|
@Type,
|
||||||
@SubjectId,
|
@SubjectId,
|
||||||
|
@SessionId,
|
||||||
@ClientId,
|
@ClientId,
|
||||||
|
@Description,
|
||||||
@CreationDate,
|
@CreationDate,
|
||||||
@ExpirationDate,
|
@ExpirationDate,
|
||||||
|
@ConsumedDate,
|
||||||
@Data
|
@Data
|
||||||
)
|
)
|
||||||
) AS [Source]
|
) AS [Source]
|
||||||
@ -29,9 +35,12 @@ BEGIN
|
|||||||
[Key],
|
[Key],
|
||||||
[Type],
|
[Type],
|
||||||
[SubjectId],
|
[SubjectId],
|
||||||
|
[SessionId],
|
||||||
[ClientId],
|
[ClientId],
|
||||||
|
[Description],
|
||||||
[CreationDate],
|
[CreationDate],
|
||||||
[ExpirationDate],
|
[ExpirationDate],
|
||||||
|
[ConsumedDate],
|
||||||
[Data]
|
[Data]
|
||||||
)
|
)
|
||||||
ON
|
ON
|
||||||
@ -41,9 +50,12 @@ BEGIN
|
|||||||
SET
|
SET
|
||||||
[Type] = [Source].[Type],
|
[Type] = [Source].[Type],
|
||||||
[SubjectId] = [Source].[SubjectId],
|
[SubjectId] = [Source].[SubjectId],
|
||||||
|
[SessionId] = [Source].[SessionId],
|
||||||
[ClientId] = [Source].[ClientId],
|
[ClientId] = [Source].[ClientId],
|
||||||
|
[Description] = [Source].[Description],
|
||||||
[CreationDate] = [Source].[CreationDate],
|
[CreationDate] = [Source].[CreationDate],
|
||||||
[ExpirationDate] = [Source].[ExpirationDate],
|
[ExpirationDate] = [Source].[ExpirationDate],
|
||||||
|
[ConsumedDate] = [Source].[ConsumedDate],
|
||||||
[Data] = [Source].[Data]
|
[Data] = [Source].[Data]
|
||||||
WHEN NOT MATCHED THEN
|
WHEN NOT MATCHED THEN
|
||||||
INSERT
|
INSERT
|
||||||
@ -51,9 +63,12 @@ BEGIN
|
|||||||
[Key],
|
[Key],
|
||||||
[Type],
|
[Type],
|
||||||
[SubjectId],
|
[SubjectId],
|
||||||
|
[SessionId],
|
||||||
[ClientId],
|
[ClientId],
|
||||||
|
[Description],
|
||||||
[CreationDate],
|
[CreationDate],
|
||||||
[ExpirationDate],
|
[ExpirationDate],
|
||||||
|
[ConsumedDate],
|
||||||
[Data]
|
[Data]
|
||||||
)
|
)
|
||||||
VALUES
|
VALUES
|
||||||
@ -61,9 +76,12 @@ BEGIN
|
|||||||
[Source].[Key],
|
[Source].[Key],
|
||||||
[Source].[Type],
|
[Source].[Type],
|
||||||
[Source].[SubjectId],
|
[Source].[SubjectId],
|
||||||
|
[Source].[SessionId],
|
||||||
[Source].[ClientId],
|
[Source].[ClientId],
|
||||||
|
[Source].[Description],
|
||||||
[Source].[CreationDate],
|
[Source].[CreationDate],
|
||||||
[Source].[ExpirationDate],
|
[Source].[ExpirationDate],
|
||||||
|
[Source].[ConsumedDate],
|
||||||
[Source].[Data]
|
[Source].[Data]
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
CREATE TABLE [dbo].[Grant] (
|
CREATE TABLE [dbo].[Grant] (
|
||||||
[Key] NVARCHAR (200) NOT NULL,
|
[Key] NVARCHAR (200) NOT NULL,
|
||||||
[Type] NVARCHAR (50) NULL,
|
[Type] NVARCHAR (50) NOT NULL,
|
||||||
[SubjectId] NVARCHAR (50) NULL,
|
[SubjectId] NVARCHAR (200) NULL,
|
||||||
[ClientId] NVARCHAR (50) NOT NULL,
|
[SessionId] NVARCHAR (100) NULL,
|
||||||
|
[ClientId] NVARCHAR (200) NOT NULL,
|
||||||
|
[Description] NVARCHAR (200) NULL,
|
||||||
[CreationDate] DATETIME2 (7) NOT NULL,
|
[CreationDate] DATETIME2 (7) NOT NULL,
|
||||||
[ExpirationDate] DATETIME2 (7) NULL,
|
[ExpirationDate] DATETIME2 (7) NULL,
|
||||||
|
[ConsumedDate] DATETIME2 (7) NULL,
|
||||||
[Data] NVARCHAR (MAX) NOT NULL,
|
[Data] NVARCHAR (MAX) NOT NULL,
|
||||||
CONSTRAINT [PK_Grant] PRIMARY KEY CLUSTERED ([Key] ASC)
|
CONSTRAINT [PK_Grant] PRIMARY KEY CLUSTERED ([Key] ASC)
|
||||||
);
|
);
|
||||||
@ -14,6 +17,10 @@ GO
|
|||||||
CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_ClientId_Type]
|
CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_ClientId_Type]
|
||||||
ON [dbo].[Grant]([SubjectId] ASC, [ClientId] ASC, [Type] ASC);
|
ON [dbo].[Grant]([SubjectId] ASC, [ClientId] ASC, [Type] ASC);
|
||||||
|
|
||||||
|
GO
|
||||||
|
CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_SessionId_Type]
|
||||||
|
ON [dbo].[Grant]([SubjectId] ASC, [SessionId] ASC, [Type] ASC);
|
||||||
|
|
||||||
GO
|
GO
|
||||||
CREATE NONCLUSTERED INDEX [IX_Grant_ExpirationDate]
|
CREATE NONCLUSTERED INDEX [IX_Grant_ExpirationDate]
|
||||||
ON [dbo].[Grant]([ExpirationDate] ASC);
|
ON [dbo].[Grant]([ExpirationDate] ASC);
|
||||||
|
267
util/Migrator/DbScripts/2020-07-30_00_IdServerv4.sql
Normal file
267
util/Migrator/DbScripts/2020-07-30_00_IdServerv4.sql
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
IF EXISTS (
|
||||||
|
SELECT * FROM sys.indexes WHERE [Name] = 'IX_Grant_SubjectId_ClientId_Type'
|
||||||
|
AND object_id = OBJECT_ID('[dbo].[Grant]')
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
DROP INDEX [IX_Grant_SubjectId_ClientId_Type]
|
||||||
|
ON [dbo].[Grant]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF EXISTS (
|
||||||
|
SELECT * FROM sys.indexes WHERE [Name] = 'IX_Grant_SubjectId_SessionId_Type'
|
||||||
|
AND object_id = OBJECT_ID('[dbo].[Grant]')
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
DROP INDEX [IX_Grant_SubjectId_SessionId_Type]
|
||||||
|
ON [dbo].[Grant]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF COL_LENGTH('[dbo].[Grant]', 'SessionId') IS NULL
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE
|
||||||
|
[dbo].[Grant]
|
||||||
|
ADD
|
||||||
|
[SessionId] NVARCHAR (100) NULL
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF COL_LENGTH('[dbo].[Grant]', 'Description') IS NULL
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE
|
||||||
|
[dbo].[Grant]
|
||||||
|
ADD
|
||||||
|
[Description] NVARCHAR (200) NULL
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF COL_LENGTH('[dbo].[Grant]', 'ConsumedDate') IS NULL
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE
|
||||||
|
[dbo].[Grant]
|
||||||
|
ADD
|
||||||
|
[ConsumedDate] DATETIME2 (7) NULL
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
[dbo].[Grant]
|
||||||
|
ALTER COLUMN
|
||||||
|
[Type] NVARCHAR (50) NOT NULL
|
||||||
|
GO
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
[dbo].[Grant]
|
||||||
|
ALTER COLUMN
|
||||||
|
[SubjectId] NVARCHAR (200) NULL
|
||||||
|
GO
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
[dbo].[Grant]
|
||||||
|
ALTER COLUMN
|
||||||
|
[ClientId] NVARCHAR (200) NOT NULL
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF EXISTS(SELECT * FROM sys.views WHERE [Name] = 'GrantView')
|
||||||
|
BEGIN
|
||||||
|
DROP VIEW [dbo].[GrantView]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE VIEW [dbo].[GrantView]
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[Grant]
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT * FROM sys.indexes WHERE [Name] = 'IX_Grant_SubjectId_ClientId_Type'
|
||||||
|
AND object_id = OBJECT_ID('[dbo].[Grant]')
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_ClientId_Type]
|
||||||
|
ON [dbo].[Grant]([SubjectId] ASC, [ClientId] ASC, [Type] ASC)
|
||||||
|
-- TODO WITH ONLINE
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT * FROM sys.indexes WHERE [Name] = 'IX_Grant_SubjectId_SessionId_Type'
|
||||||
|
AND object_id = OBJECT_ID('[dbo].[Grant]')
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_SessionId_Type]
|
||||||
|
ON [dbo].[Grant]([SubjectId] ASC, [SessionId] ASC, [Type] ASC)
|
||||||
|
-- TODO WITH ONLINE
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID('[dbo].[Grant_Delete]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Grant_Delete]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE PROCEDURE [dbo].[Grant_Delete]
|
||||||
|
@SubjectId NVARCHAR(200),
|
||||||
|
@SessionId NVARCHAR(100),
|
||||||
|
@ClientId NVARCHAR(200),
|
||||||
|
@Type NVARCHAR(50)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
DELETE
|
||||||
|
FROM
|
||||||
|
[dbo].[Grant]
|
||||||
|
WHERE
|
||||||
|
(@SubjectId IS NULL OR [SubjectId] = @SubjectId)
|
||||||
|
AND (@ClientId IS NULL OR [ClientId] = @ClientId)
|
||||||
|
AND (@SessionId IS NULL OR [SessionId] = @SessionId)
|
||||||
|
AND (@Type IS NULL OR [Type] = @Type)
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID('[dbo].[Grant_Read]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Grant_Read]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE PROCEDURE [dbo].[Grant_Read]
|
||||||
|
@SubjectId NVARCHAR(200),
|
||||||
|
@SessionId NVARCHAR(100),
|
||||||
|
@ClientId NVARCHAR(200),
|
||||||
|
@Type NVARCHAR(50)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
[dbo].[GrantView]
|
||||||
|
WHERE
|
||||||
|
(@SubjectId IS NULL OR [SubjectId] = @SubjectId)
|
||||||
|
AND (@ClientId IS NULL OR [ClientId] = @ClientId)
|
||||||
|
AND (@SessionId IS NULL OR [SessionId] = @SessionId)
|
||||||
|
AND (@Type IS NULL OR [Type] = @Type)
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID('[dbo].[Grant_Save]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Grant_Save]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE PROCEDURE [dbo].[Grant_Save]
|
||||||
|
@Key NVARCHAR(200),
|
||||||
|
@Type NVARCHAR(50),
|
||||||
|
@SubjectId NVARCHAR(200),
|
||||||
|
@SessionId NVARCHAR(100),
|
||||||
|
@ClientId NVARCHAR(200),
|
||||||
|
@Description NVARCHAR(200),
|
||||||
|
@CreationDate DATETIME2,
|
||||||
|
@ExpirationDate DATETIME2,
|
||||||
|
@ConsumedDate DATETIME2,
|
||||||
|
@Data NVARCHAR(MAX)
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON
|
||||||
|
|
||||||
|
MERGE
|
||||||
|
[dbo].[Grant] AS [Target]
|
||||||
|
USING
|
||||||
|
(
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
@Key,
|
||||||
|
@Type,
|
||||||
|
@SubjectId,
|
||||||
|
@SessionId,
|
||||||
|
@ClientId,
|
||||||
|
@Description,
|
||||||
|
@CreationDate,
|
||||||
|
@ExpirationDate,
|
||||||
|
@ConsumedDate,
|
||||||
|
@Data
|
||||||
|
)
|
||||||
|
) AS [Source]
|
||||||
|
(
|
||||||
|
[Key],
|
||||||
|
[Type],
|
||||||
|
[SubjectId],
|
||||||
|
[SessionId],
|
||||||
|
[ClientId],
|
||||||
|
[Description],
|
||||||
|
[CreationDate],
|
||||||
|
[ExpirationDate],
|
||||||
|
[ConsumedDate],
|
||||||
|
[Data]
|
||||||
|
)
|
||||||
|
ON
|
||||||
|
[Target].[Key] = [Source].[Key]
|
||||||
|
WHEN MATCHED THEN
|
||||||
|
UPDATE
|
||||||
|
SET
|
||||||
|
[Type] = [Source].[Type],
|
||||||
|
[SubjectId] = [Source].[SubjectId],
|
||||||
|
[SessionId] = [Source].[SessionId],
|
||||||
|
[ClientId] = [Source].[ClientId],
|
||||||
|
[Description] = [Source].[Description],
|
||||||
|
[CreationDate] = [Source].[CreationDate],
|
||||||
|
[ExpirationDate] = [Source].[ExpirationDate],
|
||||||
|
[ConsumedDate] = [Source].[ConsumedDate],
|
||||||
|
[Data] = [Source].[Data]
|
||||||
|
WHEN NOT MATCHED THEN
|
||||||
|
INSERT
|
||||||
|
(
|
||||||
|
[Key],
|
||||||
|
[Type],
|
||||||
|
[SubjectId],
|
||||||
|
[SessionId],
|
||||||
|
[ClientId],
|
||||||
|
[Description],
|
||||||
|
[CreationDate],
|
||||||
|
[ExpirationDate],
|
||||||
|
[ConsumedDate],
|
||||||
|
[Data]
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
[Source].[Key],
|
||||||
|
[Source].[Type],
|
||||||
|
[Source].[SubjectId],
|
||||||
|
[Source].[SessionId],
|
||||||
|
[Source].[ClientId],
|
||||||
|
[Source].[Description],
|
||||||
|
[Source].[CreationDate],
|
||||||
|
[Source].[ExpirationDate],
|
||||||
|
[Source].[ConsumedDate],
|
||||||
|
[Source].[Data]
|
||||||
|
)
|
||||||
|
;
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID('[dbo].[Grant_DeleteBySubjectIdClientId]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Grant_DeleteBySubjectIdClientId]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID('[dbo].[Grant_DeleteBySubjectIdClientIdType]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Grant_DeleteBySubjectIdClientIdType]
|
||||||
|
END
|
||||||
|
GO
|
||||||
|
|
||||||
|
IF OBJECT_ID('[dbo].[Grant_ReadBySubjectId]') IS NOT NULL
|
||||||
|
BEGIN
|
||||||
|
DROP PROCEDURE [dbo].[Grant_ReadBySubjectId]
|
||||||
|
END
|
||||||
|
GO
|
Loading…
Reference in New Issue
Block a user