public AdminFactServiceBehavior( IServiceContextAccessor context, AdminRepository adminRepo, AdminVersions versions, ILogger <AdminServiceBehavior> logger) : base(context, adminRepo, versions, logger) { }
public ApplicationServiceBehavior( IServiceContextAccessor context, IApplicationRepositoryFactory repositoryFactory, ApplicationVersions versions, AdminRepository adminRepo, ILogger <ApplicationServiceBehavior> logger) { _versions = versions; _adminRepo = adminRepo; _logger = logger; // Extract information from the Context Accessor _isServiceAccount = context.IsServiceAccount; if (_isServiceAccount) { _externalId = context.ExternalClientId ?? throw new InvalidOperationException($"The external client ID was not supplied."); } else { // This is a human user, so the external Id and email are required _externalId = context.ExternalUserId ?? throw new InvalidOperationException($"The external user ID was not supplied."); _externalEmail = context.ExternalEmail ?? throw new InvalidOperationException($"The external user email was not supplied."); } _tenantId = context.TenantId ?? throw new ServiceException($"Tenant id was not supplied."); _appRepo = repositoryFactory.GetRepository(_tenantId); _isSilent = context.IsSilent; }
public AdminServiceBehavior( IServiceContextAccessor context, AdminRepository adminRepo, AdminVersions versions, ILogger <AdminServiceBehavior> logger) { _versions = versions; _logger = logger; _isServiceAccount = context.IsServiceAccount; if (_isServiceAccount) { _externalId = context.ExternalClientId ?? throw new InvalidOperationException($"The external client ID was not supplied."); } else { // This is a human user, so the external Id and email are required _externalId = context.ExternalUserId ?? throw new InvalidOperationException($"The external user ID was not supplied."); _externalEmail = context.ExternalEmail ?? throw new InvalidOperationException($"The external user email was not supplied."); } _adminRepo = adminRepo; _isSilent = context.IsSilent; }
public PermissionsService( ApplicationServiceBehavior behavior, IServiceContextAccessor accessor, IPermissionsCache permissionsCache) : base(accessor) { _behavior = behavior; _permissionsCache = permissionsCache; }
public AdminPermissionsService( AdminServiceBehavior behavior, IServiceContextAccessor accessor, AdminRepository repo) : base(accessor) { _behavior = behavior; _repo = repo; }
public AdminSettingsService( AdminServiceBehavior behavior, AdminRepository repo, IServiceContextAccessor accessor) : base(accessor) { _behavior = behavior; _repo = repo; }
public DefinitionsService( ApplicationServiceBehavior behavior, IServiceContextAccessor contextAccessor, IDefinitionsCache definitionsCache) : base(contextAccessor) { _behavior = behavior; _definitionsCache = definitionsCache; }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBase"/> class. /// </summary> /// <param name="contextAccessor"></param> public ServiceBase(IServiceContextAccessor contextAccessor) { ExternalUserId = contextAccessor.ExternalUserId; ExternalEmail = contextAccessor.ExternalEmail; IsServiceAccount = contextAccessor.IsServiceAccount; TenantId = contextAccessor.TenantId; Today = contextAccessor.Today; Calendar = contextAccessor.Calendar; }
public async Task Invoke(HttpContext context, IServiceContextAccessor serviceContextAccessor) { try { // Collect data to go into the service context if (!Int32.TryParse(context?.Request?.Headers["ServiceVersion"].FirstOrDefault(), out int version)) { version = metadataCollection.MaxVersion; } var metadata = metadataCollection[version]; // The userDomain is meant to identify the tenant of the user who is logging in UserDomain userDomain = null; if (context.Request.Host.Host == "localhost" || context.Request.Host.Host == "127.0.0.1") { userDomain = new UserDomain { Name = context.Request.Query["userdomain"] }; } else { userDomain = new UserDomain { Name = context.Request.Host.Host.Replace('.', '_') }; } // Build the service context var serviceContext = new ServiceContext { Metadata = metadata, UserDomain = userDomain }; // Make the service context available throughout the request-handling code serviceContextAccessor.ServiceContext = serviceContext; await next.Invoke(context); } catch (ServiceException se) { logger.LogError(se.InnerException, se.Message); context.Response.StatusCode = (int)se.HttpStatusCode; await context.Response.WriteAsync(se.Message); } catch (SerializationException sze) { logger.LogError(sze, sze.Message); context.Response.StatusCode = (int)HttpStatusCode.BadRequest; await context.Response.WriteAsync(sze.Message); } catch (Exception e) { logger.LogError(e, e.Message); context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; await context.Response.WriteAsync("Unexpected server error"); } }
public FactServiceDependencies( IStringLocalizer <Strings> localizer, MetadataProvider metadata, TemplateService templateService, IServiceContextAccessor contextAccessor) { Localizer = localizer; Metadata = metadata; TemplateService = templateService; ContextAccessor = contextAccessor; }
public ReconciliationService( ApplicationServiceBehavior behavior, IServiceContextAccessor accessor, MetadataProvider metadata, IPermissionsCache permissionsCache, IStringLocalizer <Strings> localizer) : base(accessor) { _behavior = behavior; _metadata = metadata; _permissionsCache = permissionsCache; _localizer = localizer; }
public ApplicationSettingsServiceDependencies( IServiceContextAccessor context, ISettingsCache settingsCache, IPermissionsCache permissionsCache, ApplicationServiceBehavior behavior, MetadataProvider metadataProvider) { Context = context; SettingsCache = settingsCache; PermissionsCache = permissionsCache; Behavior = behavior; MetadataProvider = metadataProvider; }
public CompaniesService( IServiceContextAccessor accessor, AdminRepository db, IApplicationRepositoryFactory factory, ISettingsCache settingsCache, NullServiceBehavior behavior, ILogger <CompaniesService> logger) : base(accessor) { _adminRepo = db; _factory = factory; _settingsCache = settingsCache; _logger = logger; _behavior = behavior; }
/// <summary> /// Initializes the service with the contextual information in <paramref name="ctx"/>, this /// method must be invoked before executing any request that relies on this contextual information. /// The method also runs any custom initialization logic that is supplied by the implementing service. /// Any subsequent calls to this method will have no effect. /// </summary> protected async Task Initialize(CancellationToken cancellation = default) { // Don't run initialize more than once for the same context accessor if (_contextAccessorWhenInitialized != _contextAccessor) { _contextAccessorWhenInitialized = _contextAccessor; if (Behavior is null) { throw new InvalidOperationException($"Bug: {GetType().Name}.{nameof(Behavior)} returned null."); } _userId = await Behavior.OnInitialize(_contextAccessor, cancellation); } }
public virtual async Task <int> OnInitialize(IServiceContextAccessor context, CancellationToken cancellation) { IsInitialized = true; bool isSilent = context.IsSilent; _isAnonymous = context.IsAnonymous; // Determine if this is a userless account if (_isAnonymous) { // (1) Call OnConnect... _tenantId = context.TenantId ?? throw new ServiceException($"Tenant id was not supplied."); _appRepo = _repositoryFactory.GetRepository(_tenantId); // Retrieve the settings version and the definitions version var result = await _appRepo.OnConnect( externalUserId : null, userEmail : null, isServiceAccount : false, setLastActive : !isSilent, cancellation : cancellation); // (2) Set the versions and mark this initializer as initialized _versions.SettingsVersion = result.SettingsVersion.ToString(); _versions.DefinitionsVersion = result.DefinitionsVersion.ToString(); _versions.AreSet = true; return(0); // No user Id } else { // (1) Extract information from the Context Accessor bool isServiceAccount = context.IsServiceAccount; string externalId; string externalEmail = null; if (context.IsServiceAccount) { externalId = context.ExternalClientId ?? throw new InvalidOperationException($"The external client ID was not supplied."); } else { // This is a human user, so the external Id and email are required externalId = context.ExternalUserId ?? throw new InvalidOperationException($"The external user ID was not supplied."); externalEmail = context.ExternalEmail ?? throw new InvalidOperationException($"The external user email was not supplied."); } _tenantId = context.TenantId ?? throw new ServiceException($"Tenant id was not supplied."); _appRepo = _repositoryFactory.GetRepository(_tenantId); // (2) Call OnConnect... // The client sometimes makes ambient (silent) API calls, not in response to // user interaction, such calls should not update LastAccess of that user var result = await _appRepo.OnConnect( externalUserId : externalId, userEmail : externalEmail, isServiceAccount : isServiceAccount, setLastActive : !isSilent, cancellation : cancellation); // (3) Make sure the user is a member of this tenant if (result.UserId == null) { // Either 1) the user is not a member in the database, or 2) the database does not exist // Either way we return the not-member exception so as not to convey information to an attacker throw new ForbiddenException(notMember: true); } // Extract values from the result var userId = result.UserId.Value; var dbExternalId = result.ExternalId; var dbEmail = result.Email; // (4) If the user exists but new, set the External Id if (dbExternalId == null) { // Only possible with human users // Update external Id in this tenant database await _appRepo.Users__SetExternalIdByUserId(userId, externalId); // Update external Id in the central Admin database too (To avoid an awkward situation // where a user exists on the tenant but not on the Admin db, if they change their email in between) await _adminRepo.DirectoryUsers__SetExternalIdByEmail(externalEmail, externalId); } // (5) Handle edge case else if (dbExternalId != externalId) { // Only possible with human users // Note: there is the edge case of identity providers who allow email recycling. I.e. we can get the same email twice with // two different external Ids. This issue is so unlikely to naturally occur and cause problems here that we are not going // to handle it for now. It can however happen artificially if the application is re-configured to a new identity provider, // or if someone messed with the identity database directly, but again out of scope for now. throw new InvalidOperationException($"The sign-in email '{dbEmail}' already exists but with a different external Id. TenantId: {TenantId}."); } // (6) If the user's email address has changed at the identity server, update it locally else if (dbEmail != externalEmail && !isServiceAccount) { await _appRepo.Users__SetEmailByUserId(userId, externalEmail); await _adminRepo.DirectoryUsers__SetEmailByExternalId(externalId, externalEmail); _logger.LogWarning($"A user's email has been updated from '{dbEmail}' to '{externalEmail}'. TenantId: {TenantId}."); } // (7) Set the versions and mark this initializer as initialized _versions.SettingsVersion = result.SettingsVersion.ToString(); _versions.DefinitionsVersion = result.DefinitionsVersion.ToString(); _versions.UserSettingsVersion = result.UserSettingsVersion?.ToString(); _versions.PermissionsVersion = result.PermissionsVersion?.ToString(); _versions.AreSet = true; _userEmail = dbEmail; _userId = userId; // (8) Return the user Id return(userId); } }
public async Task <int> OnInitialize(IServiceContextAccessor context, CancellationToken cancellation) { // (1) Extract context var isServiceAccount = context.IsServiceAccount; bool isSilent = context.IsSilent; string externalId; string externalEmail = null; if (isServiceAccount) { externalId = context.ExternalClientId ?? throw new InvalidOperationException($"The external client ID was not supplied."); } else { // This is a human user, so the external Id and email are required externalId = context.ExternalUserId ?? throw new InvalidOperationException($"The external user ID was not supplied."); externalEmail = context.ExternalEmail ?? throw new InvalidOperationException($"The external user email was not supplied."); } // (2) Call OnConnect... var result = await _adminRepo.OnConnect( externalUserId : externalId, userEmail : externalEmail, isServiceAccount : isServiceAccount, setLastActive : !isSilent, cancellation : cancellation); // (3) Make sure the user is a member of the admin database if (result.UserId == null) { throw new ForbiddenException(notMember: true); } var userId = result.UserId.Value; var dbExternalId = result.ExternalId; var dbEmail = result.Email; // (4) If the user exists but new, set the External Id if (dbExternalId == null) { using var trx = TransactionFactory.ReadCommitted(); await _adminRepo.AdminUsers__SetExternalIdByUserId(userId, externalId); await _adminRepo.DirectoryUsers__SetExternalIdByEmail(externalEmail, externalId); trx.Complete(); } else if (dbExternalId != externalId) { // Note: there is the edge case of identity providers who allow email recycling. I.e. we can get the same email twice with // two different external Ids. This issue is so unlikely to naturally occur and cause problems here that we are not going // to handle it for now. It can however happen artificually if the application is re-configured to a new identity provider, // or if someone messed with the identity database directly, but again out of scope for now. throw new InvalidOperationException($"The sign-in email '{dbEmail}' already exists but with a different external Id. TenantId: Admin."); } // (5) If the user's email address has changed at the identity server, update it locally else if (dbEmail != externalEmail && !isServiceAccount) { using var trx = TransactionFactory.ReadCommitted(); await _adminRepo.AdminUsers__SetEmailByUserId(userId, externalEmail); await _adminRepo.DirectoryUsers__SetEmailByExternalId(externalId, externalEmail); _logger.LogWarning($"An admin user's email has been updated from '{dbEmail}' to '{externalEmail}'."); trx.Complete(); } // (6) Set the versions and mark this initializer as initialized _versions.UserSettingsVersion = result.UserSettingsVersion?.ToString(); _versions.PermissionsVersion = result.PermissionsVersion?.ToString(); _versions.AreSet = true; _userEmail = dbEmail; _userId = userId; IsInitialized = true; // (7) Return the user Id return(userId); }
public Task <int> OnInitialize(IServiceContextAccessor contextAccessor, CancellationToken _) => Task.FromResult(0);
public StatusController(StatusService service, IServiceContextAccessor accessor) { _service = service; _accessor = accessor; }
public ExceptionsFilter(ILogger <ExceptionsFilter> logger, IServiceContextAccessor accessor, IStringLocalizer <Strings> localizer) { _logger = logger; _accessor = accessor; _localizer = localizer; }
public StatusService(ApplicationServiceBehavior behavior, IServiceContextAccessor accessor) : base(accessor) { _behavior = behavior; }
/// <summary> /// Initializes a new instance of the <see cref="ServiceBase"/> class. /// </summary> /// <param name="contextAccessor"></param> public ServiceBase(IServiceContextAccessor contextAccessor) { // Default SetContext(contextAccessor); }
/// <summary> /// Overrides the default <see cref="IServiceContextAccessor"/> with a custom one. /// </summary> public void SetContext(IServiceContextAccessor contextAccessor) { _contextAccessor = contextAccessor; }
public async Task <int> OnInitialize(IServiceContextAccessor contextAccessor, CancellationToken cancellation) { return(await _adminBehavior.OnInitialize(contextAccessor, cancellation)); }
public WampOperation(ILogger <WampOperation> logger, IServiceContextAccessor serviceContextAccessor, IServiceScopeFactory scopeFactory) { this.logger = logger; this.serviceContextAccessor = serviceContextAccessor; this.scopeFactory = scopeFactory; }