/// <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; }
/// <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); } }