/// <summary> /// Authorization logic for Methods that has been decorated with AuthorizeActivityAttribute /// </summary> /// <param name="invocation"></param> /// <param name="authorizeAttribute"></param> private void AuthorizeMethodInvocation(IInvocation invocation, AuthorizeActivityAttribute authorizeAttribute) { foreach (var parameter in MapParameters(invocation.Arguments, invocation.Method.GetParameters(), authorizeAttribute.ParamType)) { Guid objectId; if (parameter is Guid) { objectId = (Guid)parameter; } else if (parameter is string) { objectId = Guid.Parse((string)parameter); } else { //todo: in case of requirement for objects not inherited from BaseObject, create a new property inside AuthorizeActivityAttribute that will set object inner propertyName in case of this "Id" var property = parameter.GetType().GetProperty("Id"); objectId = Guid.Parse(property.GetValue(parameter).ToString()); } if (_securityServices.AuthorizeActivity(authorizeAttribute.Permission, objectId, authorizeAttribute.TargetType.Name)) { invocation.Proceed(); } else { throw new HttpException(403, "You are not authorized to perform this activity!"); } } }
public Task <ActivateActivitiesDTO> Activate(Guid planId, bool planBuilderActivate) { if (_securityServices.AuthorizeActivity(PermissionType.EditObject, planId, nameof(PlanNodeDO))) { return(_target.Activate(planId, planBuilderActivate)); } else { throw new HttpException(403, "You are not authorized to perform this activity!"); } }
public async Task SaveOrRegister(TerminalDTO terminal) { string curEndpoint = string.Empty; // Get the value of TerminalDTO.ParticipationState which we can trust int safeParticipationState; if (UserHasTerminalAdministratorPermission()) { // We can trust Fr8 administrator (and he/she can change ParticipationState) so just get it from DTO safeParticipationState = terminal.ParticipationState; } else { if (terminal.InternalId == Guid.Empty) { // For new terminals the value is 0 (Unapproved) safeParticipationState = ParticipationState.Unapproved; } else { // We cannot trust user so get the value from the DB using (var uow = ObjectFactory.GetInstance <IUnitOfWork>()) { if (_securityService.AuthorizeActivity(PermissionType.UseTerminal, terminal.InternalId, nameof(TerminalDO))) { var terminalTempDo = uow.TerminalRepository.GetByKey(terminal.InternalId); if (terminalTempDo == null) { throw new Fr8NotFoundException(nameof(terminal.InternalId), $"Terminal with the id {terminal.InternalId} is not found."); } safeParticipationState = terminalTempDo.ParticipationState; } else { throw new HttpException(403, $"You are not authorized to use Terminal {terminal.Name}!"); } } } } terminal.ParticipationState = safeParticipationState; // Validate data if (terminal.ParticipationState == ParticipationState.Approved) { if (string.IsNullOrWhiteSpace(terminal.ProdUrl)) { throw new Fr8ArgumentNullException(nameof(terminal.ProdUrl), "Production endpoint must be specified for the terminals in the Approved state."); } curEndpoint = NormalizeUrl(terminal.ProdUrl); } else { if (string.IsNullOrWhiteSpace(terminal.DevUrl)) { throw new Fr8ArgumentNullException(nameof(terminal.DevUrl), "Development endpoint must be specified for the terminals in the Unapproved, Blocked or Deleted state."); } curEndpoint = NormalizeUrl(terminal.DevUrl); } #if DEBUG // Use local URL for Fr8 own terminals when in the local environment or during FBB tests. if (terminal.IsFr8OwnTerminal) { curEndpoint = NormalizeUrl(terminal.DevUrl); } #endif if (curEndpoint.Contains("/discover", StringComparison.OrdinalIgnoreCase)) { throw new Fr8ArgumentException(nameof(terminal.Endpoint), "Invalid terminal URL", "Terminal URL should not contain 'discover'. Please correct the URL and try again."); } if (!UserHasTerminalAdministratorPermission()) { // Developer cannot add terminals with the "localhost" endpoint, // or set it while editing, or assign a terminal the Fr8OwnTerminal flag, // or edit the terminal with such a flag. // User must be an administrator to add or edit a Fr8 own terminal. if ((new Uri(curEndpoint).Host == "localhost")) { throw new Fr8InsifficientPermissionsException("Insufficient permissions to add a 'localhost' endpoint.", "Terminal URL cannot contain the string 'localhost'. Please correct your terminal URL and try again."); } if (terminal.IsFr8OwnTerminal) { throw new Fr8InsifficientPermissionsException("Insufficient permissions to manage a Fr8Own terminal.", "Terminal URL cannot contain the string 'localhost'. Please correct your terminal URL and try again."); } } // Validating discovery response if (terminal.ParticipationState == ParticipationState.Approved || terminal.ParticipationState == ParticipationState.Unapproved) { if (!curEndpoint.Contains("://localhost")) { string errorMessage = "Terminal at the specified URL did not return a valid response to the discovery request."; try { var terminalRegistrationInfo = await SendDiscoveryRequest(curEndpoint, null); if (terminalRegistrationInfo == null) { Logger.Info($"Terminal at '{curEndpoint}' returned an invalid response."); throw new Fr8ArgumentException(nameof(terminal.Endpoint), errorMessage, errorMessage); } if (string.IsNullOrEmpty(terminalRegistrationInfo.Definition.Name)) { string validationErrorMessage = $"Validation of terminal at '{curEndpoint}' failed: Terminal Name is empty."; Logger.Info(validationErrorMessage); throw new Fr8ArgumentException(nameof(terminal.Endpoint), validationErrorMessage, validationErrorMessage); } } catch (TaskCanceledException ex) { string errorMessase = $"Terminal at '{curEndpoint}' did not respond to a /discovery request within 10 sec."; Logger.Info(errorMessase); throw new Fr8ArgumentException(nameof(terminal.Endpoint), errorMessase, "The terminal did not respond to a discovery request within 10 seconds."); } catch (Exception ex) { Logger.Info($"Terminal at '{curEndpoint}' returned an invalid response."); throw new Fr8ArgumentException(nameof(terminal.Endpoint), ex.ToString(), errorMessage); } } } var terminalDo = new TerminalDO(); terminalDo.Endpoint = terminal.Endpoint = curEndpoint; //Check whether we save an existing terminal or register a new one if (terminal.InternalId == Guid.Empty) { Logger.Info($"Registration of terminal at '{curEndpoint}' is requested. "); // New terminal if (IsExistingTerminal(curEndpoint)) { Logger.Error($"Terminal with endpoint '{curEndpoint}' was already registered"); throw new Fr8ConflictException(nameof(TerminalDO), nameof(TerminalDO.Endpoint), curEndpoint); } terminalDo.TerminalStatus = TerminalStatus.Undiscovered; // The 'Endpoint' property contains the currently active endpoint which may be changed // by deployment scripts or by promoting the terminal from Dev to Production // while ProdUrl/DevUrl contains whatever user or administrator have supplied. // Set properties which can be safely set by any user terminalDo.DevUrl = terminal.DevUrl; if (UserHasTerminalAdministratorPermission()) { // Set properties which can only be set by Administrator terminalDo.ParticipationState = terminal.ParticipationState; terminalDo.IsFr8OwnTerminal = terminal.IsFr8OwnTerminal; terminalDo.ProdUrl = terminal.ProdUrl; } else { // If a Developer adds a terminal, it has to be approved by Fr8 Administrator terminalDo.ParticipationState = ParticipationState.Unapproved; } terminalDo.UserId = Thread.CurrentPrincipal.Identity.GetUserId(); } else { // An existing terminal terminalDo.Id = terminal.InternalId; terminalDo.DevUrl = terminal.DevUrl; //Administrator can update production URL and ParticipationState if (UserHasTerminalAdministratorPermission()) { terminalDo.ProdUrl = terminal.ProdUrl; terminalDo.ParticipationState = terminal.ParticipationState; terminalDo.IsFr8OwnTerminal = terminal.IsFr8OwnTerminal; } } if (terminal.InternalId == Guid.Empty) { Logger.Info($"Proceeding to registering a new terminal: " + JsonConvert.SerializeObject(terminalDo)); } else { Logger.Info($"Proceeding to update of an existing terminal: " + JsonConvert.SerializeObject(terminalDo)); } terminalDo = _terminal.RegisterOrUpdate(terminalDo, true); Logger.Info($"Terminal at '{terminalDo.Endpoint}' (id: {terminalDo.Id}) was successfully saved."); if (terminalDo.ParticipationState == ParticipationState.Approved || terminalDo.ParticipationState == ParticipationState.Unapproved) { bool discoveryResult = (await DiscoverInternal(terminalDo, true)).IsSucceed; if (!discoveryResult) { Logger.Info($"The terminal at {curEndpoint} has been registered but an error has occurred while carrying out discovery."); } } }