/// <inheritdoc/> public virtual IAsyncEnumerable <TApplication> FindByRedirectUriAsync( string address, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(address)) { throw new ArgumentException(SR.GetResourceString(SR.ID0143), nameof(address)); } return(ExecuteAsync(cancellationToken)); async IAsyncEnumerable <TApplication> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
/// <inheritdoc/> public IAsyncEnumerable <TScope> FindByNamesAsync(ImmutableArray <string> names, CancellationToken cancellationToken) { if (names.Any(name => string.IsNullOrEmpty(name))) { throw new ArgumentException(SR.GetResourceString(SR.ID0203), nameof(names)); } // Note: this method is only partially cached. return(ExecuteAsync(cancellationToken)); async IAsyncEnumerable <TScope> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
/// <inheritdoc/> public virtual async ValueTask <TScope?> FindByNameAsync(string name, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException(SR.GetResourceString(SR.ID0202), nameof(name)); } return((await GetDatabase() .GetViewAsync(OpenIddictViews.Scope <TScope> .Name, new() { IncludeDocs = true }, cancellationToken)) .FirstOrDefault() ?.Document); }
public void ReplaceApplicationStoreResolver_ThrowsAnExceptionForInvalidStoreResolver() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws <ArgumentException>(() => builder.ReplaceApplicationStoreResolver(typeof(object))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID1231), exception.Message); }
public void Get_ThrowsAnExceptionWhenStoreCannotBeFound() { // Arrange var services = new ServiceCollection(); var provider = services.BuildServiceProvider(); var resolver = new OpenIddictTokenStoreResolver(provider); // Act and assert var exception = Assert.Throws <InvalidOperationException>(() => resolver.Get <OpenIddictToken>()); Assert.Equal(SR.GetResourceString(SR.ID0231), exception.Message); }
/// <inheritdoc/> public virtual async ValueTask <TScope?> FindByIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException(SR.GetResourceString(SR.ID0195), nameof(identifier)); } var database = await Context.GetDatabaseAsync(cancellationToken); var collection = database.GetCollection <TScope>(Options.CurrentValue.ScopesCollectionName); return(await collection.Find(scope => scope.Id == ObjectId.Parse(identifier)).FirstOrDefaultAsync(cancellationToken)); }
/// <inheritdoc/> public virtual async ValueTask <TApplication?> FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException(SR.GetResourceString(SR.ID0195), nameof(identifier)); } var database = await Context.GetDatabaseAsync(cancellationToken); var collection = database.GetCollection <TApplication>(Options.CurrentValue.ApplicationsCollectionName); return(await collection.Find(application => application.ClientId == identifier).FirstOrDefaultAsync(cancellationToken)); }
/// <inheritdoc/> public virtual async ValueTask <TScope?> FindByNameAsync(string name, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException(SR.GetResourceString(SR.ID0202), nameof(name)); } var database = await Context.GetDatabaseAsync(cancellationToken); var collection = database.GetCollection <TScope>(Options.CurrentValue.ScopesCollectionName); return(await collection.Find(scope => scope.Name == name).FirstOrDefaultAsync(cancellationToken)); }
public void Get_ThrowsAnExceptionForInvalidEntityType() { // Arrange var services = new ServiceCollection(); var provider = services.BuildServiceProvider(); var resolver = new OpenIddictMongoDbAuthorizationStoreResolver(provider); // Act and assert var exception = Assert.Throws <InvalidOperationException>(() => resolver.Get <CustomAuthorization>()); Assert.Equal(SR.GetResourceString(SR.ID0258), exception.Message); }
public async Task ExtractLogoutRequest_UnexpectedMethodReturnsAnError(string method) { // Arrange await using var server = await CreateServerAsync(options => options.EnableDegradedMode()); await using var client = await server.CreateClientAsync(); // Act var response = await client.SendAsync(method, "/connect/logout", new OpenIddictRequest()); // Assert Assert.Equal(Errors.InvalidRequest, response.Error); Assert.Equal(SR.GetResourceString(SR.ID3084), response.ErrorDescription); }
public void Get_ThrowsAnExceptionForInvalidEntityType() { // Arrange var services = new ServiceCollection(); var options = Mock.Of <IOptionsMonitor <OpenIddictEntityFrameworkCoreOptions> >(); var provider = services.BuildServiceProvider(); var resolver = new OpenIddictEntityFrameworkCoreScopeStoreResolver(new TypeResolutionCache(), options, provider); // Act and assert var exception = Assert.Throws <InvalidOperationException>(() => resolver.Get <CustomScope>()); Assert.Equal(SR.GetResourceString(SR.ID0255), exception.Message); }
/// <inheritdoc/> public virtual async ValueTask UpdateAsync(TApplication application, CancellationToken cancellationToken) { Check.NotNull(application, nameof(application)); try { await GetDatabase().AddOrUpdateAsync(application, cancellationToken: cancellationToken); } catch (CouchConflictException ex) { throw new OpenIddictExceptions.ConcurrencyException(SR.GetResourceString(SR.ID0239), ex); } }
/// <inheritdoc/> public virtual async ValueTask DeleteAsync(TScope scope, CancellationToken cancellationToken) { Check.NotNull(scope, nameof(scope)); var db = GetDatabase(); try { await db.RemoveAsync(scope, cancellationToken : cancellationToken); } catch (CouchConflictException ex) { throw new OpenIddictExceptions.ConcurrencyException(SR.GetResourceString(SR.ID0245), ex); } }
/// <inheritdoc/> public IAsyncEnumerable <TToken> FindAsync(string subject, string client, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { throw new ArgumentException(SR.GetResourceString(SR.ID0198), nameof(subject)); } if (string.IsNullOrEmpty(client)) { throw new ArgumentException(SR.GetResourceString(SR.ID0124), nameof(client)); } return(ExecuteAsync(cancellationToken)); async IAsyncEnumerable <TToken> ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
public async Task ExtractUserinfoRequest_UnexpectedMethodReturnsAnError(string method) { // Arrange await using var server = await CreateServerAsync(); await using var client = await server.CreateClientAsync(); // Act var response = await client.SendAsync(method, "/connect/userinfo", new OpenIddictRequest()); // Assert Assert.Equal(Errors.InvalidRequest, response.Error); Assert.Equal(SR.GetResourceString(SR.ID2084), response.ErrorDescription); Assert.Equal(SR.FormatID8000(SR.ID2084), response.ErrorUri); }
public void SetDefaultTokenEntity_ThrowsAnExceptionForInvalidType() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws <ArgumentException>(delegate { return(builder.SetDefaultTokenEntity(typeof(long))); }); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID1231), exception.Message); }
/// <inheritdoc/> public ValueTask HandleAsync(ValidateUserinfoRequestContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } if (string.IsNullOrEmpty(context.Request.AccessToken)) { context.Logger.LogInformation(SR.GetResourceString(SR.ID6131), Parameters.AccessToken); context.Reject( error: Errors.MissingToken, description: SR.FormatID2029(Parameters.AccessToken), uri: SR.FormatID8000(SR.ID2029)); return(default);
/// <inheritdoc/> public virtual async ValueTask DeleteAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } var database = await Context.GetDatabaseAsync(cancellationToken); var collection = database.GetCollection <TToken>(Options.CurrentValue.TokensCollectionName); if ((await collection.DeleteOneAsync(entity => entity.Id == token.Id && entity.ConcurrencyToken == token.ConcurrencyToken)).DeletedCount == 0) { throw new OpenIddictExceptions.ConcurrencyException(SR.GetResourceString(SR.ID1246)); } }
/// <inheritdoc/> public virtual async ValueTask <TApplication?> FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException(SR.GetResourceString(SR.ID0195), nameof(identifier)); } var part = $"type({Options.CurrentValue.ApplicationTypeName}))"; var query = "query Q($clientId: string)" + Options.CurrentValue.ApplicationFullQuery .Replace(part, $"eq(oidc_client_id, $clientId)) @filter({part}"); var database = await Context.GetDatabaseAsync(cancellationToken); using var txn = (Txn)database.NewTransaction(true, true, cancellationToken); var result = await txn.QueryWithVars <TApplication>("oidc_application", query, new() {
public async Task Execute_UnschedulesTriggersWhenAuthorizationManagerIsMissing() { // Arrange var provider = Mock.Of <IServiceProvider>(provider => provider.GetService(typeof(IOpenIddictAuthorizationManager)) == null); var job = CreateJob(provider); // Act and assert var exception = await Assert.ThrowsAsync <JobExecutionException>(() => job.Execute(Mock.Of <IJobExecutionContext>())); Assert.False(exception.RefireImmediately); Assert.True(exception.UnscheduleAllTriggers); Assert.True(exception.UnscheduleFiringTrigger); Assert.IsType <InvalidOperationException>(exception.InnerException); Assert.Equal(SR.GetResourceString(SR.ID0278), exception.InnerException !.Message); }
/// <inheritdoc/> public ValueTask HandleAsync(ValidateRevocationRequestContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } // Reject revocation requests missing the mandatory token parameter. if (string.IsNullOrEmpty(context.Request.Token)) { context.Logger.LogInformation(SR.GetResourceString(SR.ID6111), Parameters.Token); context.Reject( error: Errors.InvalidRequest, description: SR.FormatID2029(Parameters.Token), uri: SR.FormatID8000(SR.ID2029)); return(default);
/// <summary> /// Creates a new scope. /// </summary> /// <param name="scope">The scope to create.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <returns> /// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation. /// </returns> public virtual async ValueTask CreateAsync(TScope scope, CancellationToken cancellationToken = default) { if (scope is null) { throw new ArgumentNullException(nameof(scope)); } var results = await GetValidationResultsAsync(scope, cancellationToken); if (results.Any(result => result != ValidationResult.Success)) { var builder = new StringBuilder(); builder.AppendLine(SR.GetResourceString(SR.ID0222)); builder.AppendLine(); foreach (var result in results) { builder.AppendLine(result.ErrorMessage); } throw new OpenIddictExceptions.ValidationException(builder.ToString(), results); } await Store.CreateAsync(scope, cancellationToken); if (!Options.CurrentValue.DisableEntityCaching) { await Cache.AddAsync(scope, cancellationToken); } async Task <ImmutableArray <ValidationResult> > GetValidationResultsAsync( TScope scope, CancellationToken cancellationToken) { var builder = ImmutableArray.CreateBuilder <ValidationResult>(); await foreach (var result in ValidateAsync(scope, cancellationToken)) { builder.Add(result); } return(builder.ToImmutable()); } }
public void Get_ThrowsAnExceptionWhenDbContextTypeIsNotAvailable() { // Arrange var services = new ServiceCollection(); var options = Mock.Of <IOptionsMonitor <OpenIddictEntityFrameworkCoreOptions> >( mock => mock.CurrentValue == new OpenIddictEntityFrameworkCoreOptions { DbContextType = null }); var provider = services.BuildServiceProvider(); var resolver = new OpenIddictEntityFrameworkCoreScopeStoreResolver(new TypeResolutionCache(), options, provider); // Act and assert var exception = Assert.Throws <InvalidOperationException>(() => resolver.Get <OpenIddictEntityFrameworkCoreScope>()); Assert.Equal(SR.GetResourceString(SR.ID0253), exception.Message); }
public void AddCore_ResolvingUntypedTokenManagerThrowsAnExceptionWhenDefaultEntityIsNotSet() { // Arrange var services = new ServiceCollection(); var builder = new OpenIddictBuilder(services); // Act builder.AddCore(); // Assert var provider = services.BuildServiceProvider(); var exception = Assert.Throws <InvalidOperationException>(delegate { return(provider.GetRequiredService <IOpenIddictTokenManager>()); }); Assert.Equal(SR.GetResourceString(SR.ID0276), exception.Message); }
/// <inheritdoc/> public virtual async ValueTask <TApplication?> FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { throw new ArgumentException(SR.GetResourceString(SR.ID0195), nameof(identifier)); } var options = new CouchViewOptions <string> { Key = identifier, IncludeDocs = true }; return((await GetDatabase() .GetViewAsync(OpenIddictViews.Application <TApplication> .ClientId, options, cancellationToken) .ConfigureAwait(false)) .FirstOrDefault() ?.Document); }
/// <summary> /// Creates a new scope based on the specified descriptor. /// </summary> /// <param name="descriptor">The scope descriptor.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param> /// <returns> /// A <see cref="ValueTask"/> that can be used to monitor the asynchronous operation, whose result returns the scope. /// </returns> public virtual async ValueTask <TScope> CreateAsync( OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken = default) { if (descriptor is null) { throw new ArgumentNullException(nameof(descriptor)); } var scope = await Store.InstantiateAsync(cancellationToken); if (scope is null) { throw new InvalidOperationException(SR.GetResourceString(SR.ID0223)); } await PopulateAsync(scope, descriptor, cancellationToken); await CreateAsync(scope, cancellationToken); return(scope); }
static IReadOnlyDictionary <string, string> ReadProperties(BinaryReader reader) { // Read the version of the format used to serialize the properties. var version = reader.ReadInt32(); if (version != 1) { throw new InvalidOperationException(SR.GetResourceString(SR.ID0287)); } var count = reader.ReadInt32(); var properties = new Dictionary <string, string>(count, StringComparer.Ordinal); for (var index = 0; index != count; ++index) { properties.Add(reader.ReadString(), reader.ReadString()); } return(properties); }
/// <inheritdoc/> public ValueTask HandleAsync(ProcessRequestContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } // This handler only applies to ASP.NET Core requests. If the HTTP context cannot be resolved, // this may indicate that the request was incorrectly processed by another server stack. var request = context.Transaction.GetHttpRequest(); if (request is null) { throw new InvalidOperationException(SR.GetResourceString(SR.ID0114)); } // Only use the current host as the issuer if the // issuer was not explicitly set in the options. if (context.Issuer is not null) { return(default);
/// <inheritdoc/> public ValueTask HandleAsync(ProcessAuthenticationContext context) { if (context is null) { throw new ArgumentNullException(nameof(context)); } // Note: unlike the equivalent event in the server stack, authentication can be triggered for // arbitrary requests (typically, API endpoints that are not owned by the validation stack). // As such, the token is not directly resolved from the request, that may be null at this stage. // Instead, the token is expected to be populated by one or multiple handlers provided by the host. // // Note: this event can also be triggered by the validation service to validate an arbitrary token. if (string.IsNullOrEmpty(context.Token)) { context.Reject( error: Errors.MissingToken, description: SR.GetResourceString(SR.ID2000)); return(default);
/// <inheritdoc/> public virtual async ValueTask DeleteAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization is null) { throw new ArgumentNullException(nameof(authorization)); } var database = await Context.GetDatabaseAsync(cancellationToken); var collection = database.GetCollection <TAuthorization>(Options.CurrentValue.AuthorizationsCollectionName); if ((await collection.DeleteOneAsync(entity => entity.Id == authorization.Id && entity.ConcurrencyToken == authorization.ConcurrencyToken, cancellationToken)).DeletedCount == 0) { throw new OpenIddictExceptions.ConcurrencyException(SR.GetResourceString(SR.ID0241)); } // Delete the tokens associated with the authorization. await database.GetCollection <OpenIddictMongoDbToken>(Options.CurrentValue.TokensCollectionName) .DeleteManyAsync(token => token.AuthorizationId == authorization.Id, cancellationToken); }