Exemple #1
0
        /// <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!");
                }
            }
        }
Exemple #2
0
 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.");
                }
            }
        }