public async Task <IActionResult> Put(string resourceName, [FromBody] IroncladResource model)
        {
            if (string.Equals(resourceName, "auth_api", StringComparison.OrdinalIgnoreCase))
            {
                return(this.BadRequest(new { Message = $"Cannot modify the authorization console web API" }));
            }

            using (var session = this.store.LightweightSession())
            {
                var document = await session.Query <PostgresResource>().SingleOrDefaultAsync(item => item.Name == resourceName);

                if (document == null)
                {
                    return(this.NotFound(new { Message = $"API resource '{resourceName}' not found" }));
                }

                // NOTE (Cameron): Because of the mapping/conversion unknowns we rely upon the Postgres integration to perform that operation which is why we do this...
                var resource = new IdentityServerResource
                {
                    UserClaims = model.UserClaims,
                    Scopes     = model.ApiScopes.Select(scope => new Scope(scope.Name, scope.UserClaims)).ToList(),
                };

                // NOTE (Cameron): If the secret is updated we want to add the new secret...
                if (!string.IsNullOrEmpty(model.ApiSecret))
                {
                    resource.ApiSecrets = new List <Secret> {
                        new Secret(model.ApiSecret.Sha256())
                    };
                }

                var entity = resource.ToEntity();

                // update properties (everything supported is an optional update eg. if null is passed we will not update)
                document.DisplayName = model.DisplayName ?? document.DisplayName;
                document.UserClaims  = entity.UserClaims ?? document.UserClaims;
                document.Scopes      = entity.Scopes ?? document.Scopes;
                document.Enabled     = model.Enabled ?? document.Enabled;

                if (!string.IsNullOrEmpty(model.ApiSecret))
                {
                    document.Secrets.Add(entity.Secrets.First());
                }

                session.Update(document);

                await session.SaveChangesAsync();
            }

            return(this.Ok());
        }
        public async Task <IActionResult> Post([FromBody] IroncladResource model)
        {
            if (string.IsNullOrEmpty(model.Name))
            {
                return(this.BadRequest(new { Message = $"Cannot create an API resource without a name" }));
            }

            if (string.IsNullOrEmpty(model.ApiSecret))
            {
                return(this.BadRequest(new { Message = $"Cannot create an API resource without a secret" }));
            }

            var resource = new IdentityServerResource(model.Name, model.DisplayName)
            {
                ApiSecrets = new List <Secret> {
                    new Secret(model.ApiSecret.Sha256())
                },
            };

            // optional properties
            resource.UserClaims = model.UserClaims ?? resource.UserClaims;
            resource.Scopes     = model.ApiScopes?.Select(item => new Scope(item.Name, item.UserClaims)).ToList() ?? resource.Scopes;
            resource.Enabled    = model.Enabled ?? resource.Enabled;

            using (var session = this.store.LightweightSession())
            {
                if (session.Query <PostgresResource>().Any(document => document.Name == model.Name))
                {
                    return(this.StatusCode((int)HttpStatusCode.Conflict, new { Message = "API resource already exists" }));
                }

                session.Insert(resource.ToEntity());

                await session.SaveChangesAsync();
            }

            return(this.Created(new Uri(this.HttpContext.GetIdentityServerRelativeUrl("~/api/apiresources/" + model.Name)), null));
        }