public static MethodAuthorization GetMethodAuthorization(this MethodInfoData method) { object[] attr = method.MethodInfo.GetCustomAttributes(false).ToArray(); MethodAuthorization methodAuthorization = new MethodAuthorization { MethodName = method.MethodInfo.Name, AuthorizeData = Enumerable.Empty <IAuthorizeData>(), IsOverride = false, IsAllowAnonymous = attr.Where(a => a is IAllowAnonymous).Any() }; if (methodAuthorization.IsAllowAnonymous) { return(methodAuthorization); } IAuthorizeData[] denies = attr.Where(a => a is IDenyAuthorizeData).Cast <IAuthorizeData>().ToArray(); IAuthorizeData[] overrides = attr.Where(a => a is IOverrideAuthorizeData).Cast <IAuthorizeData>().ToArray(); if (overrides.Any()) { methodAuthorization.IsOverride = true; methodAuthorization.AuthorizeData = Enumerable.Union(denies, overrides); return(methodAuthorization); } IAuthorizeData[] permits = attr.Where(a => a is IAuthorizeData && !(a is IDenyAuthorizeData) && !(a is IOverrideAuthorizeData)).Cast <IAuthorizeData>().ToArray(); methodAuthorization.AuthorizeData = Enumerable.Union(denies, permits); return(methodAuthorization); }
/// <summary> /// throws AccesDeniedExeption if user have no rights to execute operation /// </summary> /// <param name="changeSet"></param> public async Task CheckUserRightsToExecute(MethodInfoData method) { if (!await CanAccessMethod(method)) { string user = User == null || User.Identity == null || !User.Identity.IsAuthenticated ? ANONYMOUS_USER : User.Identity.Name; throw new AccessDeniedException(string.Format(ErrorStrings.ERR_USER_ACCESS_DENIED, user)); } }
public static MethodInfo GetMethod(this TypeResolver typeResolver, MethodInfoData methodInfoData) { if (methodInfoData != null) { return(typeResolver.GetMethod(typeResolver.GetType(methodInfoData.DeclaringType), methodInfoData.Name, typeResolver.GetTypes(methodInfoData.ParameterTypes), typeResolver.GetTypes(methodInfoData.GenericArgumentTypes))); } return(null); }
public static bool CanAccessMethod(MethodInfoData method, IAuthorizer authorizer) { try { authorizer.CheckUserRightsToExecute(method); return(true); } catch (AccessDeniedException) { return(false); } }
/// <summary> /// throws AccesDeniedExeption if user have no rights to execute operation /// </summary> /// <param name="changeSet"></param> public void CheckUserRightsToExecute(MethodInfoData method) { var roles = SecurityHelper.GetRoleTree(GetRolesForService(), new[] { method }); if (!CheckAccess(roles)) { var user = principal == null || principal.Identity == null || !principal.Identity.IsAuthenticated ? ANONYMOUS_USER : principal.Identity.Name; throw new AccessDeniedException(string.Format(ErrorStrings.ERR_USER_ACCESS_DENIED, user)); } }
/// <summary> /// Generates Data Services' method description which is convertable to JSON /// and can be consumed by clients /// </summary> public static MethodDescription FromMethodInfo(MethodInfoData data, IServiceContainer container) { var methDescription = new MethodDescription(data); //else Result is Converted to JSON var paramsInfo = data.methodInfo.GetParameters(); for (var i = 0; i < paramsInfo.Length; ++i) { var param = ParamMetadata.FromParamInfo(paramsInfo[i], container); param.ordinal = i; methDescription.parameters.Add(param); } return(methDescription); }
public static RolesForMethod GetRolesForMethod(MethodInfoData method) { var method_roles = new RolesForMethod { MethodName = method.methodInfo.Name, Roles = new string[0], IsRolesOverride = false }; var roles_list = new LinkedList <string>(); //the override attribute replaces all other roles for the method var override_roles = method.methodInfo.GetCustomAttribute <OverrideAuthorizeAttribute>(false); if (override_roles != null) { method_roles.IsRolesOverride = true; method_roles.Roles = override_roles.Roles.Select(a => a.Trim()).Distinct().ToArray(); return(method_roles); } var attrs = method.methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), false).OfType <AuthorizeAttribute>(); if (attrs.Count() == 0) { //allow unauthenticated access var passthrough_attrs = method.methodInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute), false) .OfType <AllowAnonymousAttribute>(); if (passthrough_attrs.Any()) { roles_list.AddLast(ALLOW_ANONYMOUS); } } else { //at least user must be authenticated roles_list.AddLast(AUTHENTICATED); foreach (var attr in attrs) { var attr_roles = attr.Roles.Select(a => a.Trim()); foreach (var role in attr_roles) { roles_list.AddLast(role); } } } method_roles.Roles = roles_list.Distinct().ToArray(); return(method_roles); }
public object GetMethodOwner(MethodInfoData methodData) { if (!methodData.isInDataManager) { return(_domainService); } if (methodData.entityType == null) { return(_domainService); } var metadata = MetadataHelper.GetInitializedMetadata(_domainService); var managerInstance = _dataManagers.GetOrAdd(methodData.entityType, t => { return(metadata.DataManagerContainer.GetDataManager(_domainService, t)); }); return(managerInstance); }
public object GetMethodOwner(MethodInfoData methodData) { if (!methodData.IsInDataManager) { return(_domainService); } if (methodData.EntityType == null) { return(_domainService); } RunTimeMetadata metadata = _domainService.GetMetadata(); object managerInstance = _dataManagers.GetOrAdd(methodData.EntityType, t => { return(_dataManagerContainer.GetDataManager(t)); }); return(managerInstance); }
public static DbSetPermit GetDbSetPermissions(CachedMetadata metadata, string dbSetName, IAuthorizer authorizer) { MethodInfoData method = null; var permit = new DbSetPermit(); permit.dbSetName = dbSetName; method = metadata.getOperationMethodInfo(dbSetName, MethodType.Insert); permit.canAddRow = method != null && CanAccessMethod(method, authorizer); method = metadata.getOperationMethodInfo(dbSetName, MethodType.Update); permit.canEditRow = method != null && CanAccessMethod(method, authorizer); method = metadata.getOperationMethodInfo(dbSetName, MethodType.Delete); permit.canDeleteRow = method != null && CanAccessMethod(method, authorizer); method = metadata.getOperationMethodInfo(dbSetName, MethodType.Refresh); permit.canRefreshRow = method != null && CanAccessMethod(method, authorizer); return(permit); }
public async Task Invoke(RefreshContext <TService> ctx) { DbSetInfo dbSetInfo = ctx.Request.GetDbSetInfo() ?? throw new InvalidOperationException($"Could not get the DbSet for {ctx.Request.dbSetName}"); Security.IAuthorizer <TService> authorizer = ctx.ServiceContainer.GetAuthorizer(); RunTimeMetadata metadata = ctx.Service.GetMetadata(); MethodInfoData methodData = metadata.GetOperationMethodInfo(ctx.Request.dbSetName, MethodType.Refresh); if (methodData == null) { throw new InvalidOperationException(string.Format(ErrorStrings.ERR_REC_REFRESH_INVALID, dbSetInfo.GetEntityType().Name, GetType().Name)); } await authorizer.CheckUserRightsToExecute(methodData); await _next(ctx); }
/// <summary> /// Invokes the method with the specified name and parameters. /// </summary> /// <param name="type">The object instance to invoke upon.</param> /// <param name="methodName">The name of the method to invoke.</param> /// <param name="parameters">The parameters to run the method with.</param> /// <returns>The value returned by the invoked method.</returns> public static object InvokeMethod(this object type, string methodName, params object[] parameters) { MethodInfoData methodInfoData = new MethodInfoData(type.GetType(), methodName, parameters.Select(x => x.GetType()).ToArray()); if (!cachedMethods.ContainsKey(methodInfoData)) { cachedMethods.Add(methodInfoData, type.GetType().GetMethod(methodName, methodInfoData.parameters)); } MethodInfo method = cachedMethods[methodInfoData]; if (method != null) { return(method.Invoke(type, parameters)); } else { throw new InvalidOperationException("No method was found with the specified name and parameters!"); } }
public async Task Invoke(QueryContext <TService> ctx) { DbSetInfo dbSetInfo = ctx.Request.GetDbSetInfo() ?? throw new InvalidOperationException($"Could not get the DbSet for {ctx.Request.dbSetName}"); IDataHelper <TService> dataHelper = ctx.ServiceContainer.GetDataHelper(); IServiceOperationsHelper <TService> serviceHelper = ctx.ServiceContainer.GetServiceHelper(); RunTimeMetadata metadata = ctx.Service.GetMetadata(); MethodDescription method = metadata.GetQueryMethod(ctx.Request.dbSetName, ctx.Request.queryName); LinkedList <object> methParams = new LinkedList <object>(); for (int i = 0; i < method.parameters.Count; ++i) { methParams.AddLast(ctx.Request.paramInfo.GetValue(method.parameters[i].name, method, dataHelper)); } RequestContext req = QueryContext <TService> .CreateRequestContext(ctx.Service, ctx.Request); using (RequestCallContext callContext = new RequestCallContext(req)) { MethodInfoData methodData = method.GetMethodData(); object instance = serviceHelper.GetMethodOwner(methodData); object invokeRes = methodData.MethodInfo.Invoke(instance, methParams.ToArray()); QueryResult queryResult = (QueryResult)await serviceHelper.GetMethodResult(invokeRes); IEnumerable <object> entities = queryResult.Result; int? totalCount = queryResult.TotalCount; RowGenerator rowGenerator = new RowGenerator(dbSetInfo, entities, dataHelper); IEnumerable <Row> rows = rowGenerator.CreateRows(); SubsetsGenerator subsetsGenerator = new SubsetsGenerator(metadata, dataHelper); SubsetList subResults = subsetsGenerator.CreateSubsets(queryResult.subResults); ctx.Response.names = dbSetInfo.GetNames(); ctx.Response.totalCount = totalCount; ctx.Response.rows = rows; ctx.Response.subsets = subResults; ctx.Response.extraInfo = queryResult.extraInfo; } await _next(ctx); }
public static MethodInfoData GetCRUDMethodInfo(CachedMetadata metadata, string dbSetName, RowInfo rowInfo) { MethodInfoData method = null; switch (rowInfo.changeType) { case ChangeType.Added: method = metadata.getOperationMethodInfo(dbSetName, MethodType.Insert); break; case ChangeType.Deleted: method = metadata.getOperationMethodInfo(dbSetName, MethodType.Delete); break; case ChangeType.Updated: method = metadata.getOperationMethodInfo(dbSetName, MethodType.Update); break; default: throw new DomainServiceException(string.Format(ErrorStrings.ERR_REC_CHANGETYPE_INVALID, dbSetName, rowInfo.changeType)); } return(method); }
public MethodDescription(MethodInfoData data) { methodData = data; parameters = new List <ParamMetadata>(); }
public Task <bool> CanAccessMethod(MethodInfoData method) { AuthorizationTree authorizationTree = GetServiceAuthorization().GetAuthorizationTree(new[] { method }); return(CheckAccess(authorizationTree)); }
public async Task <bool> ValidateEntity(RunTimeMetadata metadata, RequestContext requestContext) { RowInfo rowInfo = requestContext.CurrentRowInfo; DbSetInfo dbSetInfo = rowInfo.GetDbSetInfo(); IEnumerable <ValidationErrorInfo> errs1 = null; IEnumerable <ValidationErrorInfo> errs2 = null; LinkedList <string> mustBeChecked = new LinkedList <string>(); LinkedList <string> skipCheckList = new LinkedList <string>(); if (rowInfo.changeType == ChangeType.Added) { foreach (ParentChildNode pn in rowInfo.GetChangeState().ParentRows) { foreach (FieldRel frel in pn.Association.fieldRels) { skipCheckList.AddLast(frel.childField); } } } foreach (Field fieldInfo in dbSetInfo.fieldInfos) { _dataHelper.ForEachFieldInfo("", fieldInfo, (fullName, f) => { if (!f.GetIsIncludeInResult()) { return; } if (f.fieldType == FieldType.Object || f.fieldType == FieldType.ServerCalculated) { return; } string value = _dataHelper.SerializeField(rowInfo.GetChangeState().Entity, fullName, f); switch (rowInfo.changeType) { case ChangeType.Added: { bool isSkip = f.isAutoGenerated || skipCheckList.Any(n => n == fullName); if (!isSkip) { _validationHelper.CheckValue(f, value); mustBeChecked.AddLast(fullName); } } break; case ChangeType.Updated: { bool isChanged = isEntityValueChanged(rowInfo, fullName, f, out string newVal); if (isChanged) { _validationHelper.CheckValue(f, newVal); mustBeChecked.AddLast(fullName); } } break; } }); } rowInfo.GetChangeState().ChangedFieldNames = mustBeChecked.ToArray(); MethodInfoData methodData = metadata.GetOperationMethodInfo(dbSetInfo.dbSetName, MethodType.Validate); if (methodData != null) { object instance = GetMethodOwner(methodData); object invokeRes = methodData.MethodInfo.Invoke(instance, new[] { rowInfo.GetChangeState().Entity, rowInfo.GetChangeState().ChangedFieldNames }); errs1 = (IEnumerable <ValidationErrorInfo>) await GetMethodResult(invokeRes); } if (errs1 == null) { errs1 = Enumerable.Empty <ValidationErrorInfo>(); } IValidator validator = _validatorsContainer.GetValidator(rowInfo.GetDbSetInfo().GetEntityType()); if (validator != null) { errs2 = await validator.ValidateModelAsync(rowInfo.GetChangeState().Entity, rowInfo.GetChangeState().ChangedFieldNames); } if (errs2 == null) { errs2 = Enumerable.Empty <ValidationErrorInfo>(); } errs1 = errs1.Concat(errs2); rowInfo.GetChangeState().ValidationErrors = errs1.ToArray(); return(rowInfo.GetChangeState().ValidationErrors.Length == 0); }
public static async Task <bool> CanAccessOperation(this IAuthorizer authorizer, RunTimeMetadata metadata, string dbSetName, MethodType methodType) { MethodInfoData method = metadata.GetOperationMethodInfo(dbSetName, methodType); return(method != null && await authorizer.CanAccessMethod(method)); }