/// <inheritdoc /> public IEnumerable <DatabaseIndex> Select(IRequest <DatabaseIndex> request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } return(Db.SQL <Index>(AllIndexes) .Where(index => !index.Table.FullName.StartsWith("Starcounter.")) .Where(index => !index.Table.FullName.StartsWith("RESTar.Admin.")) .Where(index => !index.Name.StartsWith("DYNAMIT_GENERATED_INDEX")) .Select(index => (resource: Resource.ByTypeName(index.Table.FullName), index)) .Where(pair => pair.resource != null) .Select(pair => { var properties = pair.resource.Type .GetDeclaredProperties() .Values .Where(p => p.ScIndexableColumn != null) .ToLookup(p => p.ScIndexableColumn); return new DatabaseIndex(pair.resource.Name) { Name = pair.index.Name, Columns = Db.SQL <IndexedColumn>(ColumnByIndex, pair.index) .Select(c => { var name = properties[c.Column].FirstOrDefault()?.Name ?? c.Column.Name; return new ColumnInfo(name, c.Ascending == 0); }) .ToArray() }; }) .Where(request.Conditions) .ToList()); }
private bool RemoveProceduralResource(Type resourceType) { var iresource = Resource.SafeGet(resourceType); if (iresource == null) { return(true); } return(RemoveResource(iresource)); }
private static void ReadApiKeys(JToken apiKeyToken) { IEnumerable <string> recurseApiKeys(JToken token) { switch (token) { case JObject apiKey: var keyString = apiKey["Key"].Value <string>(); if (keyString == null || Regex.IsMatch(keyString, @"[\(\)]") || !Regex.IsMatch(keyString, RegEx.ApiKey)) { throw new Exception("An API key contained invalid characters. Must be a non-empty string, not containing " + "whitespace or parentheses, and only containing ASCII characters 33 through 126"); } var key = keyString.SHA256(); IEnumerable <AccessRight> recurseAllowAccess(JToken allowAccessToken) { switch (allowAccessToken) { case JObject allowAccess: IEnumerable <IResource> recurseResources(JToken resourceToken) { switch (resourceToken) { case JValue value when value.Value is string resourceString: var iresources = Resource.SafeFindMany(resourceString); var includingInner = iresources.Union(iresources .Cast <IResourceInternal>() .Where(r => r.InnerResources != null) .SelectMany(r => r.InnerResources)); foreach (var resource in includingInner) { yield return(resource); } yield break; case JArray resources: foreach (var resource in resources.SelectMany(recurseResources)) { yield return(resource); } yield break; default: throw new Exception("Invalid API key XML syntax in config file"); } } yield return(new AccessRight ( resources: recurseResources(allowAccess["Resource"]) .OrderBy(r => r.Name) .ToList(), allowedMethods: allowAccess["Methods"] .Value <string>() .ToUpper() .ToMethodsArray() )); yield break; case JArray allowAccesses: foreach (var allowAccess in allowAccesses.SelectMany(recurseAllowAccess)) { yield return(allowAccess); } yield break; default: throw new Exception("Invalid API key XML syntax in config file"); } } var accessRights = AccessRights.ToAccessRights(recurseAllowAccess(token["AllowAccess"]), key); foreach (var resource in Resources.Where(r => r.GETAvailableToAll)) { if (accessRights.TryGetValue(resource, out var methods)) { accessRights[resource] = methods .Union(new[] { GET, REPORT, HEAD }) .OrderBy(i => i, MethodComparer.Instance) .ToArray(); } else { accessRights[resource] = new[] { GET, REPORT, HEAD } }; } if (Authenticator.ApiKeys.TryGetValue(key, out var existing)) { existing.Clear(); accessRights.ForEach(pair => existing[pair.Key] = pair.Value); } else { Authenticator.ApiKeys[key] = accessRights; } yield return(key); yield break; case JArray apiKeys: foreach (var _key in apiKeys.SelectMany(recurseApiKeys)) { yield return(_key); } yield break; default: throw new Exception("Invalid API key XML syntax in config file"); } } var currentKeys = recurseApiKeys(apiKeyToken).ToList(); Authenticator.ApiKeys.Keys.Except(currentKeys).ToList().ForEach(key => { if (Authenticator.ApiKeys.TryGetValue(key, out var accessRights)) { WebSocketController.RevokeAllWithKey(key); accessRights.Clear(); } Authenticator.ApiKeys.Remove(key); }); }