public override void OnAuthorization(AuthorizationContext context) { Logger.Trace("OnAuthorization"); if (Permissions == null) { throw new InvalidOperationException("No permission sets found"); } if (PrincipalProvider == null) { throw new InvalidOperationException("No principal provider found"); } var user = PrincipalProvider.GetCurrent(); var authorized = actions.Any(action => Permissions.CanPerform(user, resourceType, action)); if (authorized) { return; } context.Result = new HttpForbiddenResult(); Logger.Warn("unauthorized access detected by {0}", user == null ? "Anonymous" : user.Identity.Name); }
/// <inheritdoc/> protected override async Task <ResultModel> ProtectedHandleAsync(GetByIdQuery request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } Expression <Func <ResultEntity, bool> > expression = PredicateBuilder.Create <ResultEntity>(e => e.Id == Guid.Parse(request.Id)); if (!principal.IsInRole(RoleType.Administrator)) { expression = expression.And(e => e.Task.Object.UserId == principal.Identity.Name); } var entity = await Context.ResultRepository.GetFirstOrDefaultAsync(expression, cancellationToken); if (entity == null) { throw new NotFoundException(nameof(ResultEntity), request.Id); } return(ResultModel.Create(entity, Serializer)); }
/// <inheritdoc/> protected override async Task <EventModel> ProtectedHandleAsync(GetByIdQuery request, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } Expression <Func <EventEntity, bool> > expression = PredicateBuilder.Create <EventEntity>(e => e.Id == Guid.Parse(request.Id)); if (!principal.IsInRole(RoleType.Administrator)) { expression = expression.And(e => e.UserId == principal.Identity.Name); } var result = Context.EventRepository .GetQuery() .Where(expression) .FirstOrDefault(); if (result == null) { throw new NotFoundException(nameof(WebhookEntity), request.Id); } var model = EventModel.Create(result, Serializer); await Task.CompletedTask; return(model); }
/// <summary> /// Attempts to sign in the specified <paramref name="principal"/>. /// </summary> /// <param name="principal">The principal to sign in.</param> /// <returns>Instance of <see cref="TokenContext"/>.</returns> public virtual ValueTask <TokenContext> SignInAsync(ClaimsPrincipal principal) { if (principal is null) { throw new ArgumentNullException(nameof(principal)); } var(user, tenant) = PrincipalProvider.GetUserAndTenant <User, Organization>(principal); if (user is null || tenant is null) { throw new AuthenticationException(); } Claim claim = principal.FindFirst(FunderMapsAuthenticationClaimTypes.TenantRole); if (claim is null) { throw new AuthenticationException(); } Logger.LogTrace($"User '{user}' sign in was successful."); principal = PrincipalProvider.CreateTenantUserPrincipal(user, tenant, Enum.Parse <OrganizationRole>(claim.Value), JwtBearerDefaults.AuthenticationScheme); return(new(TokenProvider.GetTokenContext(principal))); }
/// <summary> /// Asynchronously handles the command request. /// </summary> /// <param name="request">The command request.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A task that represents the asynchronous operation. /// The task result contains the result of the command request.</returns> public async Task <TResponse> Handle(TRequest request, CancellationToken cancellationToken) { try { cancellationToken.ThrowIfCancellationRequested(); var response = await ProtectedHandleAsync(request, cancellationToken); if (SubEventType != SubEventType.None) { var principal = PrincipalProvider.GetPrincipal(); var auditData = new AuditDataModel() { Entity = response, Command = request }; await Audit.AddDefaultEventAsync(principal, auditData, SubEventType); } return(response); } catch (Exception) { Context.RollBackTransaction(); throw; } }
protected override System.Threading.Tasks.Task <HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { AuthenticationHeaderValue authValue = request.Headers.Authorization; if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter)) { Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter); if (parsedCredentials != null) { Thread.CurrentPrincipal = PrincipalProvider .CreatePrincipal(parsedCredentials.Username, parsedCredentials.Password); request.GetRequestContext().Principal = Thread.CurrentPrincipal; } } return(base.SendAsync(request, cancellationToken) .ContinueWith(task => { var response = task.Result; if (response.StatusCode == HttpStatusCode.Unauthorized && !response.Headers.Contains(BasicAuthResponseHeader)) { response.Headers.Add(BasicAuthResponseHeader , BasicAuthResponseHeaderValue); } return response; })); }
/// <inheritdoc/> protected override async Task <PaginationResultModel <EventModel> > ProtectedHandleAsync(GetPaginatedQuery request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } Expression <Func <EventEntity, bool> > expression = PredicateBuilder.True <EventEntity>(); if (!principal.IsInRole(RoleType.Administrator)) { expression = expression.And(e => e.UserId == principal.Identity.Name); } int total = await Context.EventRepository.CountAsync(expression, cancellationToken); var query = Context.EventRepository .GetQuery(expression) .OrderByDescending(e => e.CreatedDate) .Skip(request.Page * request.Limit) .Take(request.Limit); var entities = await Context.ToListAsync(query, cancellationToken); var models = entities.Select(e => EventModel.Create(e, Serializer)); return(PaginationResultModel <EventModel> .Create(models, request.Page, request.Limit, total)); }
public override void TestFixtureSetUp() { var cryptoProvider = new SHA2CryptoProvider(HashAlgorithm.SHA256); var principalProvider = new PrincipalProvider(cryptoProvider); this.TokenProvider = new SentinelTokenProvider(cryptoProvider, principalProvider); base.TestFixtureSetUp(); }
/// <inheritdoc/> protected override async Task <FileByteResultModel> ProtectedHandleAsync(GetZipQuery request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } Expression <Func <ResultEntity, bool> > expression = PredicateBuilder.Create <ResultEntity>(e => e.Id == Guid.Parse(request.Id)); if (!principal.IsInRole(RoleType.Administrator)) { expression = expression.And(e => e.Task.Object.UserId == principal.Identity.Name); } var entity = await Context.ResultRepository.GetFirstOrDefaultAsync(expression, cancellationToken); if (entity == null) { throw new NotFoundException(nameof(ResultEntity), request.Id); } if (string.IsNullOrWhiteSpace(entity.BasePath)) { throw new UnexpectedNullException($"The base path of result {request.Id} is null."); } var fs = fileSystemStrategy.Create(configuration.Options.WorkingDirectory); if (fs == null) { throw new UnexpectedNullException("Filesystem could not be created based on the working directory."); } var fullBasePath = fs.Path.Combine(configuration.Options.WorkingDirectory, entity.BasePath); var items = fs.Directory.EnumerateFiles(fullBasePath, "*.*", SearchOption.TopDirectoryOnly); var archive = writer.Create(CompressionType.None); await writer.AddFilesAsync(items, dfp => dfp, en => en.Substring(fullBasePath.Length), archive, cancellationToken); var stream = new MemoryStream(); writer.Write(stream, archive); var result = new FileByteResultModel() { FileContents = stream.ToArray(), ContentType = "application/zip", FileDownloadName = $"{Constants.ApplicationNameShort}_{request.Id}_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.zip" }; return(result); }
public override void SetUp() { var principalProvider = new PrincipalProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512)); var tokenRepository = new MemoryTokenRepository(); this.TokenManager = new TokenManager( LogManager.GetLogger(typeof(MemoryTokenManagerTests)), principalProvider, new SentinelTokenProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512), principalProvider), tokenRepository); base.SetUp(); }
/// <summary> /// Ensures AD objects (for console mode purposes). /// </summary> private static void EnsureObjects() { MessageLog.LogEvent(ResHelper.GetString("Console_LoadingObjectFromAD")); if ((ImportProfile.ImportUsersType == ImportType.All) || (ImportProfile.ImportUsersType == ImportType.UpdateSelectedImportNew)) { PrincipalProvider.LoadAllUsers(); } if ((ImportProfile.ImportRolesType == ImportType.All) || (ImportProfile.ImportRolesType == ImportType.UpdateSelectedImportNew)) { PrincipalProvider.LoadAllGroups(); } }
public override void SetUp() { var principalProvider = new PrincipalProvider(new SHA2CryptoProvider(HashAlgorithm.SHA256)); var tokenRepository = new RavenDbTokenRepository( new RavenDbTokenRepositoryConfiguration(new EmbeddableDocumentStore() { RunInMemory = true }, LogManager.GetLogger <RavenDbTokenManagerTests>())); this.TokenManager = new TokenManager( LogManager.GetLogger(typeof(RavenDbTokenManagerTests)), principalProvider, new SentinelTokenProvider(new SHA2CryptoProvider(HashAlgorithm.SHA256), principalProvider), tokenRepository); base.SetUp(); }
public override void SetUp() { var connectionStringBuilder = this.instance.CreateConnectionStringBuilder(); connectionStringBuilder.SetInitialCatalogName(this.databaseName); var principalProvider = new PrincipalProvider(new PBKDF2CryptoProvider()); var tokenRepository = new SqlServerTokenRepository(connectionStringBuilder.ToString()); this.TokenManager = new TokenManager( LogManager.GetLogger(typeof(SqlServerTokenManagerTests)), principalProvider, new SentinelTokenProvider(new SHA2CryptoProvider(HashAlgorithm.SHA256), principalProvider), tokenRepository); base.SetUp(); }
/// <summary> /// Deletes domain objects that exist in CMS and doesn't exist in AD. /// </summary> /// <param name="usersChanged">Records removed users for CMS event log.</param> /// <param name="rolesChanged">Records removed roles for CMS event log.</param> private static void DeleteNonExistingObjects(CumulatedChanges usersChanged, CumulatedChanges rolesChanged) { // Remove CMS (domain) roles that do not exist in AD anymore IQueryable <RoleInfo> excessiveRoles = RoleInfo.Provider .Get() .WhereTrue("RoleIsDomain") .WhereNotEquals("RoleGUID", Guid.Empty) .WhereGreaterThan("RoleID", 0) .Columns("RoleID", "RoleGUID", "RoleName") .Where(x => !PrincipalProvider.Exists(x.RoleGUID)); foreach (var role in excessiveRoles) { // Delete role RoleInfo.Provider.Delete(role); // Store deleted role GUID and name for EventLog rolesChanged.Add(role.RoleGUID, role.RoleDisplayName, ChangeActionEnum.Deleted); // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_DeletingRole", role.RoleDisplayName)); } // Remove CMS (domain) users that do not exist in AD anymore IQueryable <UserInfo> excessiveUsers = UserInfo.Provider .Get() .WhereTrue("UserIsDomain") .WhereNotEquals("UserGUID", Guid.Empty) .WhereGreaterThan("UserID", 0) .Columns("UserID", "UserGUID", "UserName") .Where(x => !PrincipalProvider.Exists(x.UserGUID)); foreach (var user in excessiveUsers) { // Delete user UserInfo.Provider.Delete(user); // Store deleted user GUID and name for EventLog usersChanged.Add(user.UserGUID, user.UserName, ChangeActionEnum.Deleted); // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_DeletingUser", user.UserName)); } }
public override void SetUp() { var principalProvider = new PrincipalProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512)); var tokenRepository = new RedisTokenRepository( new RedisTokenRepositoryConfiguration( ConfigurationManager.AppSettings["RedisHost"], 4, "sentinel.oauth.RedisTokenManagerTests", LogManager.GetLogger(typeof(RedisTokenManagerTests)))); this.TokenManager = new TokenManager( LogManager.GetLogger(typeof(RedisTokenManagerTests)), principalProvider, new SentinelTokenProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512), principalProvider), tokenRepository); base.SetUp(); }
/// <summary> /// Attempts to sign in the specified <paramref name="email"/> and <paramref name="password"/> combination. /// </summary> /// <param name="email">The user email to sign in.</param> /// <param name="password">The password to attempt to authenticate.</param> /// <returns>Instance of <see cref="TokenContext"/>.</returns> public virtual async Task <TokenContext> PasswordSignInAsync(string email, string password) { if (await UserRepository.GetByEmailAsync(email) is not IUser user) { throw new AuthenticationException(); } // FUTURE: Single call? var organizationId = await OrganizationUserRepository.GetOrganizationByUserIdAsync(user.Id); if (await CheckPasswordAsync(user.Id, password)) { if (await UserRepository.GetAccessFailedCount(user.Id) > 10) { Logger.LogWarning($"User '{user}' locked out."); throw new AuthenticationException(); } await UserRepository.ResetAccessFailed(user.Id); await UserRepository.RegisterAccess(user.Id); Logger.LogInformation($"User '{user}' password sign in was successful."); Organization organization = await OrganizationRepository.GetByIdAsync(organizationId); OrganizationRole organizationRole = await OrganizationUserRepository.GetOrganizationRoleByUserIdAsync(user.Id); ClaimsPrincipal principal = PrincipalProvider.CreateTenantUserPrincipal(user, organization, organizationRole, JwtBearerDefaults.AuthenticationScheme); return(TokenProvider.GetTokenContext(principal)); } Logger.LogWarning($"User '{user}' failed to provide the correct password."); await UserRepository.BumpAccessFailed(user.Id); throw new AuthenticationException(); }
/// <inheritdoc/> protected override async Task <ObjectModel> ProtectedHandleAsync(GetByIdQuery request, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } Expression <Func <ObjectEntity, bool> > expression = PredicateBuilder.Create <ObjectEntity>(e => e.Id == Guid.Parse(request.Id)); if (!principal.IsInRole(RoleType.Administrator)) { expression = expression.And(e => e.UserId == principal.Identity.Name); } var result = Context.ObjectRepository .GetQuery() .Where(expression) .Select(e => new { Object = e, Tasks = e.Tasks.OrderByDescending(e1 => e1.CreatedDate).Take(Constants.DefaultPaginationLimit), Results = e.Tasks.OrderByDescending(e1 => e1.CreatedDate).Select(e1 => e1.Result).Take(Constants.DefaultPaginationLimit) }) .FirstOrDefault(); if (result == null) { throw new NotFoundException(nameof(ObjectEntity), request.Id); } var model = ObjectModel.Create(result.Object, result.Tasks, result.Results, Serializer); await Task.CompletedTask; return(model); }
public override void TestFixtureSetUp() { var client = new Client() { ClientId = "NUnit", ClientSecret = "10000:gW7zpVeugKl8IFu7TcpPskcgQjy4185eAwBk9fFlZK6JNd1I45tLyCYtJrzWzE+kVCUP7lMSY8o808EjUgfavBzYU/ZtWypcdCdCJ0BMfMcf8Mk+XIYQCQLiFpt9Rjrf5mAY86NuveUtd1yBdPjxX5neMXEtquNYhu9I6iyzcN4=:Lk2ZkpmTDkNtO/tsB/GskMppdAX2bXehP+ED4oLis0AAv3Q1VeI8KL0SxIIWdxjKH0NJKZ6qniRFkfZKZRS2hS4SB8oyB34u/jyUlmv+RZGZSt9nJ9FYJn1percd/yFA7sSQOpkGljJ6OTwdthe0Bw0A/8qlKHbO2y2M5BFgYHY=", RedirectUri = "http://localhost", Enabled = true }; var user = new User() { UserId = "azzlack", Password = "******", FirstName = "Ove", LastName = "Andersen", Enabled = true }; var clientRepository = new Mock <IClientRepository>(); clientRepository.Setup(x => x.GetClient("NUnit")).ReturnsAsync(client); clientRepository.Setup(x => x.GetClients()).ReturnsAsync(new List <IClient>() { client }); var userRepository = new Mock <IUserRepository>(); userRepository.Setup(x => x.GetUser("azzlack")).ReturnsAsync(user); userRepository.Setup(x => x.GetUsers()).ReturnsAsync(new List <IUser>() { user }); this.Server = TestServer.Create( app => { var principalProvider = new PrincipalProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512)); var tokenProvider = new SentinelTokenProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512), principalProvider); app.UseSentinelAuthorizationServer( new SentinelAuthorizationServerOptions() { ClientRepository = clientRepository.Object, UserRepository = userRepository.Object, TokenProvider = tokenProvider, IssuerUri = new Uri("https://sentinel.oauth") }); // Start up web api var httpConfig = new HttpConfiguration(); httpConfig.MapHttpAttributeRoutes(); // Configure Web API to use only Bearer token authentication. httpConfig.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); httpConfig.EnsureInitialized(); app.UseWebApi(httpConfig); }); base.TestFixtureSetUp(); }
/// <inheritdoc/> protected override async Task <TaskModel> ProtectedHandleAsync(CreateTaskCommand request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } if (request.Command.CommandType != CommandType.ProcessObjectCommand || request.Command.GetType() != typeof(ProcessObjectCommand)) { throw new NotSupportedException("The provided command type is not supported."); } var command = request.Command as ProcessObjectCommand; Guid objectId = Guid.Parse(command.Id); var objectOwnerId = Context.ObjectRepository.GetQuery(e => e.Id == objectId).Select(e => e.UserId).FirstOrDefault(); if (!AuthService.IsAuthorized(objectOwnerId)) { throw new ForbiddenException("Not authorized"); } processMutex = new Mutex(false, this.GetMethodName()); return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() => { var activeCount = await Context.TaskRepository.CountAsync(e => e.ObjectId == objectId && (e.Status == (int)Domain.Enums.TaskStatus.Created || e.Status == (int)Domain.Enums.TaskStatus.Queued || e.Status == (int)Domain.Enums.TaskStatus.Processing)); if (activeCount > 0) { throw new AmiException("The specified object is already actively being processed."); } var position = await Context.TaskRepository.CountAsync(e => e.Status == (int)Domain.Enums.TaskStatus.Queued); var entity = new TaskEntity() { Id = idGenerator.GenerateId(), CreatedDate = DateTime.UtcNow, ModifiedDate = DateTime.UtcNow, QueuedDate = DateTime.UtcNow, Status = (int)Domain.Enums.TaskStatus.Queued, Progress = 0, Position = position, CommandType = (int)CommandType.ProcessObjectCommand, CommandSerialized = serializer.Serialize(command), UserId = principal.Identity.Name, ObjectId = objectId }; Context.TaskRepository.Add(entity); await Context.SaveChangesAsync(cancellationToken); var result = await mediator.Send(new GetByIdQuery() { Id = entity.Id.ToString() }); if (result == null) { throw new UnexpectedNullException($"The task '{entity.Id.ToString()}' could not be retrieved after creating it."); } if (entity.Object != null) { await Events.CreateAsync(entity.Object.UserId, EventType.TaskCreated, result, cancellationToken); await Gateway.NotifyGroupsAsync(entity.Object.UserId, EventType.TaskCreated, result, cancellationToken); } backgroundService.EnqueueTask(result.Id); return result; })); }
/// <inheritdoc/> protected override async Task <ObjectModel> ProtectedHandleAsync(CreateObjectCommand request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } int objectLimit = 0; if (principal.IsInRole(RoleType.User)) { objectLimit = apiConfiguration.Options.ObjectLimit; } else { objectLimit = apiConfiguration.Options.ObjectLimitAnonymous; } processMutex = new Mutex(false, this.GetMethodName()); return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() => { if (objectLimit > 0) { var count = await Context.ObjectRepository.CountAsync(e => e.UserId == principal.Identity.Name, cancellationToken); if (count >= objectLimit) { throw new AmiException($"The object limit of {objectLimit} has been reached."); } } string fileExtension = fileSystem.Path.GetExtension(request.OriginalFilename); Guid guid = idGenerator.GenerateId(); string path = fileSystem.Path.Combine("Binary", "Objects", guid.ToString()); string destFilename = string.Concat(guid.ToString(), fileExtension); string destPath = fileSystem.Path.Combine(path, destFilename); fileSystem.Directory.CreateDirectory(fileSystem.Path.Combine(appConfiguration.Options.WorkingDirectory, path)); fileSystem.File.Move(request.SourcePath, fileSystem.Path.Combine(appConfiguration.Options.WorkingDirectory, destPath)); var entity = new ObjectEntity() { Id = guid, CreatedDate = DateTime.UtcNow, ModifiedDate = DateTime.UtcNow, OriginalFilename = request.OriginalFilename, SourcePath = destPath, UserId = principal.Identity.Name }; Context.ObjectRepository.Add(entity); await Context.SaveChangesAsync(cancellationToken); var result = ObjectModel.Create(entity); await Events.CreateAsync(entity.UserId, EventType.ObjectCreated, result, cancellationToken); await Gateway.NotifyGroupsAsync(entity.UserId, EventType.ObjectCreated, result, cancellationToken); return result; })); }
private static void ImportWorker_DoWork(object sender, DoWorkEventArgs e) { try { BackgroundWorker worker = (BackgroundWorker)sender; // Save import profile if (ImportProfile.SaveImportProfile && !ImportProfile.UsesConsole) { SaveFile(SaveImportProfile); } // Decide whether to import if (!ImportProfile.ImportNow && !ImportProfile.UsesConsole) { return; } using (new CMSActionContext() { LogEvents = false, ContinuousIntegrationAllowObjectSerialization = false }) { #region "Initialization" // Import canceled if (worker.CancellationPending) { e.Cancel = true; return; } DateTime start = DateTime.Now; // Initialize CMS context CMSInit(); if (ImportProfile.UsesConsole) { // Ensure object in case they are not present in import profile EnsureObjects(); } if (ImportProfile.ImportUsersOnlyFromSelectedRoles) { // Narrow down imported users according to imported roles ImportProfile.Users.Clear(); } // Import canceled if (worker.CancellationPending) { e.Cancel = true; return; } // Initialize cumulative changed users and roles storages var rolesChanged = new CumulatedChanges(WellKnownEventLogEventsEnum.RolesCreated, WellKnownEventLogEventsEnum.RolesUpdated, WellKnownEventLogEventsEnum.RolesDeleted); var usersChanged = new CumulatedChanges(WellKnownEventLogEventsEnum.UsersCreated, WellKnownEventLogEventsEnum.UsersUpdated, WellKnownEventLogEventsEnum.UsersDeleted); #endregion // Delete non-existing objects (this also prevents conflicting code names) if (ImportProfile.DeleteNotExistingObjects) { DeleteNonExistingObjects(usersChanged, rolesChanged); } #region "Role import" foreach (var siteInfo in ImportProfile .Sites .Select(site => SiteInfo.Provider.Get(site.Key)) .Where(info => info != null)) { foreach (Guid groupGuid in ImportProfile.Groups) { // Import canceled if (worker.CancellationPending) { e.Cancel = true; return; } // Try to get group IPrincipalObject group = PrincipalProvider.GetPrincipalObject(groupGuid); // If group is still null if (group == null) { MessageLog.LogEvent(ResHelper.GetString("Log_SkippingNonExistingObject")); warnings++; // If deleting of not existing objects is enabled if (ImportProfile.DeleteNotExistingObjects) { DeleteRole(siteInfo, groupGuid); } } else { // Get role description string roleDescription = String.Empty; if (ImportProfile.ImportRoleDescription && (group.Description != null)) { roleDescription = group.Description; } // Get correct role name format string roleCodeName = group.GetCMSCodeName(true); // Get role display name string roleDisplayName = group.GetCMSDisplayName(); // Get safe role name roleCodeName = ValidationHelper.GetSafeRoleName(roleCodeName, siteInfo.SiteName); if (!String.IsNullOrEmpty(roleCodeName)) { // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_ImportingRole", roleDisplayName, CMS.Helpers.ResHelper.LocalizeString(siteInfo.DisplayName))); // Import role ImportRole(roleCodeName, roleDisplayName, siteInfo.SiteID, roleDescription, groupGuid, ImportProfile.UpdateObjectData, rolesChanged); if (ImportProfile.ImportUsersOnlyFromSelectedRoles) { ImportProfile.Users.AddRange(PrincipalProvider.GetUsersOf(group).Select(u => u.Identifier)); } } else { // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_SkippingEmptyRolename", group.Identifier)); warnings++; } } } } // Log created and updated and removed roles to EventLog rolesChanged.WriteEventsToEventLog(); #endregion #region "User import" foreach (var user in ImportProfile .Users .Distinct() .Select(userGuid => PrincipalProvider.GetPrincipalObject(userGuid))) { // Import canceled if (worker.CancellationPending) { e.Cancel = true; return; } if (user == null) { MessageLog.LogEvent(ResHelper.GetString("Log_SkippingNonExistingObject")); continue; } string domainName = user.GetCMSCodeName(true); if (!String.IsNullOrEmpty(domainName)) { // Get user info object UserInfo userInfo = (UserInfo.Provider.Get((Guid)user.Identifier) ?? UserInfo.Provider.Get(domainName)); bool newUser = (userInfo == null); // When is desired to import new users only from selected roles if (newUser && ImportProfile.ImportNewUsersOnlyFromSelectedRoles) { // Skip users that does not belong to one of selected role bool skip = ImportProfile.Groups.Cast <Guid>().All(groupGuid => !user.IsPrincipalInGroup(groupGuid)); if (skip) { MessageLog.LogEvent(ResHelper.GetString("Log_SkippingDoesNotBelongToSelectedRole", domainName)); continue; } } if (ImportProfile.UpdateObjectData || newUser) { if (userInfo == null) { userInfo = new UserInfo(); // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_ImportingUser", domainName)); } else { // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_UpdatingUser", domainName)); } using (var transaction = new CMSTransactionScope()) { if (newUser) { userInfo.UserIsDomain = true; userInfo.UserGUID = (Guid)user.Identifier; // Set privilege level UserPrivilegeLevelEnum privilegeLevel = ImportProfile.ConfigureAsCMSEditor ? UserPrivilegeLevelEnum.Editor : UserPrivilegeLevelEnum.None; userInfo.SiteIndependentPrivilegeLevel = privilegeLevel; } if (userInfo.UserIsDomain) { // Set user's properties userInfo.UserIsExternal = true; userInfo.UserName = domainName; userInfo.Enabled = ValidationHelper.GetBoolean(user.Enabled, true); // Bind properties foreach (KeyValuePair <string, string> property in ImportProfile.UserProperties) { // Get attribute object attribute = user.GetProperty(property.Value); if (attribute != null) { try { string attrValue; // Get string representation of the attribute if (attribute is float || attribute is double || attribute is decimal) { attrValue = String.Format(CultureInfo.InvariantCulture, "{0}", attribute); } else if (attribute.GetType() == typeof(byte[])) { attrValue = PrincipalProvider.GetSID(attribute); } else if (attribute.GetType().BaseType == typeof(MarshalByRefObject)) { attrValue = PrincipalProvider.GetTimeFromInterval(attribute); } else { attrValue = attribute.ToString(); } // Set property userInfo.SetValue(property.Key, LimitLengthForField(attrValue, property.Key)); } catch { MessageLog.LogEvent(ResHelper.GetString("Log_ErrorParsingAttr", property.Value)); warnings++; } } else { FormFieldInfo field = UserFormInfo.GetFormField(property.Key); userInfo.SetValue(property.Key, field.GetPropertyValue(FormFieldPropertyEnum.DefaultValue)); } } // Create full name if empty if (String.IsNullOrEmpty(userInfo.FullName)) { userInfo.FullName = user.GetCMSDisplayName(); } // Store user info object and its user-settings if (userInfo.ChangedColumns().Any()) { // Store created/updated user for EventLog // User name is used, because AD accounts does not have to have first and/or given name specified (e.g. Guest, …) usersChanged.Add(userInfo.UserGUID, userInfo.UserName, newUser ? ChangeActionEnum.Created : ChangeActionEnum.Updated); UserInfo.Provider.Set(userInfo); } } else { MessageLog.LogEvent(ResHelper.GetString("Log_UserIsNotDomain", userInfo.UserName)); warnings++; } transaction.Commit(); } } else { MessageLog.LogEvent(ResHelper.GetString("Log_SkippingExistingUser", domainName)); } // Import canceled if (worker.CancellationPending) { e.Cancel = true; return; } // Assign user to sites and roles (for domain users only) if (!userInfo.UserIsDomain) { continue; } #region "Membership (roles) synchronization" if (!newUser && !ImportProfile.UpdateMemberships && !ImportProfile.UpdateMemberships) { // No membership synchronization will be performed continue; } // Initialize collection to cumulate membership changes var memberShipChanges = new CumulatedRolesMembership(); // Load all user roles from DB var userRoles = new HashSet <RoleInfo>(newUser ? Enumerable.Empty <RoleInfo>() // non-existing user cannot be present in a single role (in DB) : RoleInfo.Provider .Get() .WhereIn("RoleID", UserRoleInfo.Provider .Get() .WhereEquals("UserID", userInfo.UserID) .Column("RoleID")) .Columns("RoleID", "RoleGUID", "RoleDisplayName", "RoleIsDomain")); // Store user's roles before membership synchronization memberShipChanges.SetRolesBefore(userRoles); foreach (KeyValuePair <string, List <Guid> > site in ImportProfile.Sites) { // Get site info object var siteInfo = SiteInfo.Provider.Get(site.Key); if (siteInfo != null) { try { // Add user to this site UserSiteInfo.Provider.Add(userInfo.UserID, siteInfo.SiteID); } catch (Exception ex) { MessageLog.LogEvent(ResHelper.GetString("Log_GeneralWarning", ex.Message)); warnings++; } // Assign user to roles already existing in CMS if (newUser || ImportProfile.UpdateMemberships) { SetMemberships(user, userInfo, siteInfo, userRoles, site); } // Remove user from roles they is member no more if (!newUser && ImportProfile.UpdateMemberships) { RemoveExcessiveMemberships(user, userInfo, userRoles); } } else { MessageLog.LogEvent(ResHelper.GetString("Log_SiteNotExist", site.Key)); warnings++; } } // Store user's roles after membership synchronization memberShipChanges.SetRolesAfter(userRoles); // Log created and removed memberships to EventLog memberShipChanges.WriteEventsToEventLog(userInfo.UserName); #endregion } else { // Add message to log MessageLog.LogEvent(ResHelper.GetString("Log_SkippingEmptyUsername", user.Identifier)); warnings++; } } // Log created and updated and deleted users to EventLog usersChanged.WriteEventsToEventLog(); #endregion // Import canceled if (worker.CancellationPending) { e.Cancel = true; return; } TimeSpan duration = DateTime.Now - start; if (!worker.CancellationPending) { // Add message to log MessageLog.LogEvent(warnings == 0 ? ResHelper.GetString("Log_ImportComplete", duration.Hours, duration.Minutes, duration.Seconds) : ResHelper.GetString("Log_ImportCompleteWithWarnings", warnings, duration.Hours, duration.Minutes, duration.Seconds)); } } } catch (Exception ex) { MessageLog.LogError(ResHelper.GetString("Error_General"), ex); } }
public override void TestFixtureSetUp() { base.TestFixtureSetUp(); var client = new Client() { ClientId = "NUnit", ClientSecret = this.PasswordCryptoProvider.CreateHash("PFJTQUtleVZhbHVlPjxNb2R1bHVzPnFKMEtXaXZWSjUxUWtKWGdIU1hidkxOTEJsa09rOE9uSWtvRTljU1FrRzhOZm5VYXBrWHpkTlEvb3FLZE9BSWxYK1hFMnNwN0xFcS9KRnJMaDRNblhRPT08L01vZHVsdXM+PEV4cG9uZW50PkFRQUI8L0V4cG9uZW50PjxQPnljRXBJUDJseG1oa0hRMGRrKzRBVk1lZDhWRUFFVHN5TXgvL3NaNS9TbFU9PC9QPjxRPjFmTEVGWU1JMk1TMUJQbzYwcnYyQmhkYWNBaTI2d2Z0V1N2OVl0aUdnT2s9PC9RPjxEUD5uZ0dYTW0wejdXVklNckJZMzhmZm5vWVBIalR2dG84RHk2SmQ0RDlmTlZrPTwvRFA+PERRPk5FZEQzclhNSFp2RFY5b0ZNYVU0TXJqV0luWWVyRU9kbmFLQUlmMGlzTEU9PC9EUT48SW52ZXJzZVE+ZGQzNVh6T0RvUlZQaXQxb2REL0lKRHpXdUtYMXZrb2NjcXQ4REZGVTlwVT08L0ludmVyc2VRPjxEPkFBcC80VW1oSmFJcm9DcWJ5eXdRbDViY0xFMXNSSkwxek50dllkdGxNTCsxWVFRdWx6YzVPRkh1WUcxQW56OE8vbXU2MXNDN0dNVm04ZTVqSUp6SldRPT08L0Q+PC9SU0FLZXlWYWx1ZT4="), //ClientSecret = "10000:gW7zpVeugKl8IFu7TcpPskcgQjy4185eAwBk9fFlZK6JNd1I45tLyCYtJrzWzE+kVCUP7lMSY8o808EjUgfavBzYU/ZtWypcdCdCJ0BMfMcf8Mk+XIYQCQLiFpt9Rjrf5mAY86NuveUtd1yBdPjxX5neMXEtquNYhu9I6iyzcN4=:Lk2ZkpmTDkNtO/tsB/GskMppdAX2bXehP+ED4oLis0AAv3Q1VeI8KL0SxIIWdxjKH0NJKZ6qniRFkfZKZRS2hS4SB8oyB34u/jyUlmv+RZGZSt9nJ9FYJn1percd/yFA7sSQOpkGljJ6OTwdthe0Bw0A/8qlKHbO2y2M5BFgYHY=", PublicKey = "PFJTQUtleVZhbHVlPjxNb2R1bHVzPnFKMEtXaXZWSjUxUWtKWGdIU1hidkxOTEJsa09rOE9uSWtvRTljU1FrRzhOZm5VYXBrWHpkTlEvb3FLZE9BSWxYK1hFMnNwN0xFcS9KRnJMaDRNblhRPT08L01vZHVsdXM+PEV4cG9uZW50PkFRQUI8L0V4cG9uZW50PjwvUlNBS2V5VmFsdWU+", RedirectUri = "http://localhost", Enabled = true }; var user = new User() { UserId = "azzlack", Password = this.PasswordCryptoProvider.CreateHash("aabbccddee"), //Password = "******", FirstName = "Ove", LastName = "Andersen", Enabled = true }; var userApiKeys = new List <IUserApiKey>() { new UserApiKey() { UserId = "azzlack", ApiKey = "PFJTQUtleVZhbHVlPjxNb2R1bHVzPnlidFpyM0pWS0p1L2hlUFMrV0Zla1kyYmRYVDlJMU1MeHZheTlIMW9IenRwRmI4QzJtQmUzY1EzVDhjUzE0ajJ4bk9lRkt2YVZ4Ukw5S2ozd0tOL1B3PT08L01vZHVsdXM+PEV4cG9uZW50PkFRQUI8L0V4cG9uZW50PjwvUlNBS2V5VmFsdWU+" } }; var clientRepository = new Mock <IClientRepository>(); clientRepository.Setup(x => x.GetClient("NUnit")).ReturnsAsync(client); clientRepository.Setup(x => x.GetClients()).ReturnsAsync(new List <IClient>() { client }); var userRepository = new Mock <IUserRepository>(); userRepository.Setup(x => x.GetUser("azzlack")).ReturnsAsync(user); userRepository.Setup(x => x.GetUsers()).ReturnsAsync(new List <IUser>() { user }); var userApiKeyRepository = new Mock <IUserApiKeyRepository>(); userApiKeyRepository.Setup(x => x.GetForUser("azzlack")).ReturnsAsync(userApiKeys); this.Server = TestServer.Create( app => { var principalProvider = new PrincipalProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512)); var tokenProvider = new SentinelTokenProvider(new SHA2CryptoProvider(HashAlgorithm.SHA512), principalProvider); app.UseSentinelAuthorizationServer( new SentinelAuthorizationServerOptions() { RequireSecureConnection = false, EnableBasicAuthentication = true, EnableSignatureAuthentication = true, ClientRepository = clientRepository.Object, UserRepository = userRepository.Object, UserApiKeyRepository = userApiKeyRepository.Object, TokenProvider = tokenProvider, IssuerUri = new Uri("https://sentinel.oauth") }); // Start up web api var httpConfig = new HttpConfiguration(); httpConfig.MapHttpAttributeRoutes(); // Configure Web API to use only Bearer token authentication. httpConfig.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); httpConfig.EnsureInitialized(); app.UseWebApi(httpConfig); }); }
/// <inheritdoc/> protected override async Task <WebhookModel> ProtectedHandleAsync(CreateWebhookCommand request, CancellationToken cancellationToken) { var principal = PrincipalProvider.GetPrincipal(); if (principal == null) { throw new ForbiddenException("Not authenticated"); } int webhookLimit; if (principal.IsInRole(RoleType.Administrator)) { webhookLimit = 0; } else { webhookLimit = apiConfiguration.Options.WebhookLimit; } processMutex = new Mutex(false, this.GetMethodName()); return(await processMutex.Execute(new TimeSpan(0, 0, 2), async() => { if (webhookLimit > 0) { var count = await Context.WebhookRepository.CountAsync( e => e.UserId == principal.Identity.Name, cancellationToken); if (count >= webhookLimit) { throw new AmiException($"The webhook limit of {webhookLimit} has been reached."); } } Guid guid = idGenerator.GenerateId(); string enabledEvents = request.EnabledEvents.Contains(constants.WildcardCharacter) ? constants.WildcardCharacter.Embed(constants.ValueSeparator) : request.EnabledEvents.ToArray().ToString(",", constants.ValueSeparator); var entity = new WebhookEntity() { Id = guid, CreatedDate = DateTime.UtcNow, ModifiedDate = DateTime.UtcNow, Url = request.Url, ApiVersion = request.ApiVersion, Secret = request.Secret, EnabledEvents = enabledEvents, UserId = principal.Identity.Name }; Context.WebhookRepository.Add(entity); await Context.SaveChangesAsync(cancellationToken); var result = WebhookModel.Create(entity, constants); return result; })); }