Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of <see cref="PermissionModel"/> for Controller
        /// </summary>
        /// <param name="attribute">The attribute.</param>
        /// <param name="controllerType">Type of the controller.</param>
        public PermissionModel(IPermissionAttribute attribute, Type controllerType)
        {
            this.Permission = attribute.Permission;
            this.Area       = attribute.Area.IsNullOrWhiteSpace() ?
                              ActiveRoleEngineHelper.GetControllerArea(controllerType) :
                              attribute.Area;
            this.Controller = attribute.Controller.IsNullOrWhiteSpace() ?
                              ActiveRoleEngineHelper.GetControllerName(controllerType) :
                              attribute.Controller;
            this.Action = attribute.Action;

            this.Group          = attribute.Group;
            this.Description    = attribute.Description;
            this.PermissionType = attribute.PermissionType;
        }
Beispiel #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PermissionModel" /> class for Action
        /// </summary>
        /// <param name="attribute">The attribute</param>
        /// <param name="controllerAttribute">The controller attribute if any</param>
        /// <param name="controllerType">Type of the controller</param>
        /// <param name="methodInfo">The method information</param>
        public PermissionModel(IPermissionAttribute attribute,
                               IPermissionAttribute controllerAttribute,
                               Type controllerType,
                               MemberInfo methodInfo)
        {
            // if the Action is decorated by ActivePermissionAttribute
            // it will be considered a new permission (unless it map to an existing permission)


            // get permission decoration from ActivePermissionAttribute
            // if ActivePermissionAttribute does not provide the information
            // then get from MethodInfo or controllerAttribute


            // not inherit from controller, the action must define its own
            this.Permission = attribute.Permission;

            // inherit from controller if not defined
            // Area can be "" (root area) => here we check null only
            this.Area = attribute.Area ?? ActiveRoleEngineHelper.GetControllerArea(controllerType);

            // inherit from controller if not defined
            // Controller must be specified

            if (attribute.Controller.IsNotNullOrEmpty())
            {
                this.Controller = attribute.Controller;
            }
            else
            {
                this.Controller = controllerAttribute == null || controllerAttribute.Controller.IsNullOrWhiteSpace() ?
                                  ActiveRoleEngineHelper.GetControllerName(controllerType) :
                                  controllerAttribute.Controller;
            }

            if (attribute.Action.IsNotNullOrEmpty())
            {
                this.Action = attribute.Action;
            }
            else
            {
                string actionName = null;

                if (methodInfo.IsDefined(typeof(ActionNameAttribute)))
                {
                    actionName = methodInfo.GetCustomAttribute <ActionNameAttribute>()?.Name;
                }

                if (actionName.IsNullOrEmpty())
                {
                    actionName = methodInfo.Name;
                }

                this.Action = actionName;
            }

            // the Action does not define the group => inherit from controller
            this.Group = attribute.Group.IsNullOrWhiteSpace() ? controllerAttribute?.Group : attribute.Group;

            this.Description = attribute.Description;

            this.PermissionType = attribute.PermissionType;

            //// if AllowSuperAdminOnlyEnum.Inherit then get from controller
            //this.PermissionType = attribute.PermissionType == PermissionType.Inherit ?
            //    (controllerAttribute?.PermissionType ?? PermissionType.Inherit) :
            //    attribute.PermissionType;
        }
        // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.

        /**
         * Authorization flow:
         * - First time, the OnAuthorization will be invoked
         * + If the authorization is skip, the action process will continue
         * + Else, the cache handler will be added
         * - So in both case (cache and no-cache), the authorization will call AuthorizeCore to validate
         *
         * */

        /// <summary>
        /// Main point to authorize the user
        /// </summary>
        /// <param name="filterContext">The filter context of the action</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">httpContext</exception>
        /// <exception cref="System.Exception">SystemPermissions is not defined</exception>
        protected virtual AuthorizeResult AuthorizeUser(AuthorizationContext filterContext)
        {
            // Note: use the filterfilterContext so that we may get the controller's attribute
            if (filterContext == null)
            {
                throw new ArgumentNullException(nameof(filterContext));
            }

            HttpContextBase httpContext = filterContext.HttpContext;

            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            IUserPermission user = ActiveUserEngine.CurrentUser;

            // no user data => unauthorized
            if (user == null)
            {
                return(AuthorizeResult.FailedNotLoggedIn);
            }

            // TODO: temp disable
            // always authorize system admin
            if (user.IsSuperAdmin)
            {
                return(AuthorizeResult.Success);
            }

            // FROM NOW, USER IS NOT SUPER ADMIN

            // TODO:
            // https://www.ryadel.com/en/asp-net-mvc-fix-ambiguous-action-methods-errors-multiple-action-methods-action-name-c-sharp-core/
            // Get the MethodInfo of the action
            // https://stackoverflow.com/questions/1972234/how-do-i-get-a-methodinfo-from-an-actionexecutingcontext

            MethodInfo methodInfo     = filterContext.ActionDescriptor.GetMethodInfo();
            Type       controllerType = filterContext.ActionDescriptor.ControllerDescriptor.ControllerType;

            PermissionModel permission = null;

            if (ActiveRoleEngine.PermissionDictionaryCache.ContainsKey(methodInfo))
            {
                permission = ActiveRoleEngine.PermissionDictionaryCache[methodInfo];
            }
            else if (ActiveRoleEngine.PermissionDictionaryCache.ContainsKey(controllerType))
            {
                permission = ActiveRoleEngine.PermissionDictionaryCache[controllerType];
            }

            if (permission == null)
            {
                // this should not happen, anyway, throw an exception for debugging

                string actionNamespace = ActiveRoleEngineHelper.GetDebugNamespace(methodInfo);

                throw new SystemException($"FATAL ERROR: cannot found the defined permission for '{actionNamespace}'");
            }

            // to display the permission on error page
            this.AuthorizingPermissionId = permission.PermissionId;

            switch (permission.PermissionType)
            {
            case PermissionType.Authenticated:
                // ActiveUserEngine.CurrentUser is not null => Authenticated
                return(AuthorizeResult.Success);

            case PermissionType.AuthorizedInternal:
                // only authorize internal user
                return(user.IsInternalUser ? AuthorizeResult.Success : AuthorizeResult.FailedNotAuthorized);

            case PermissionType.AuthorizedExternal:
                // only authorize external user
                return(user.IsExternalUser ? AuthorizeResult.Success : AuthorizeResult.FailedNotAuthorized);

            case PermissionType.SuperAdmin:
                // user must be super admin
                return(user.IsSuperAdmin ? AuthorizeResult.Success : AuthorizeResult.FailedSuperAdminOnly);

            //case PermissionType.Permisson:
            default:
                // user must be granted permission to access
                if (user.Permissions == null || !user.Permissions.Contains(permission.PermissionId))
                {
                    return(AuthorizeResult.FailedNotAuthorized);
                }

                return(AuthorizeResult.Success);
            }
        }