I am trying to update a field in a model that extends the user model. In the API explorer, I set the where field to {"id": 59}, and have the access token one that corresponds with id 59. In the data field I have {"age": 55} where I am just trying to update the age to 55.
The request URL ends up being: http://IP:3000/api/MODEL/update?where=%7B%22id%22%3A%2059%7D&access_token=LONG ACCESS TOKEN VALUE
Which gives an error:
{
"error": {
"statusCode": 401,
"name": "Error",
"message": "Authorization Required",
"code": "AUTHORIZATION_REQUIRED",
}
}
I don't understand why authorization is required when I have a correct access token and the email has been verified. What am I doing wrong?
Loopback by default provides ACL to user model. So by default the update operation can only be changed by the $OWNER, ie. the person himself.
So first login with the username and password, you get the accesstoken. Copy and set the accesstoken in Api Explorer.
Now use the PUT method, which will say Users/{$id}
Open it and you will see 2 fields, data and id. Provide your model's id and provide the data object (the data that needs to be changed)
Hope this helps.
Related
In most OpenAPI 3.0 documentation (like the official one), links are introduced with a combination of a POST endpoint to create an entity returning an ID linking to a GET endpoint to fetch that entity by that same returned ID:
POST /users -> UserID
GET /users/{UserID} -> User
In Schemathesis context, this would assume an empty data storage and simulate a create+fetch scenario. I would like to test my GET endpoints on a pre-warmed data storage and implement a "fetch a list, then fetch each entity from the list by ID" scenario:
GET /users -> List[User] -> List[UserID]
GET /users/{UserID} -> User for each entry in the list
For this to work, I need an OpenAPI link from the list GET endpoint to the entity GET endpoint, however I can't seem to find either an example or a confirmation that this is indeed possible.
Can I and if so how can I create such a link in OpenAPI 3.0?
OpenAPI links are defined using JSON Pointers. JSON Pointers are quite limited - they can only point to a specific field within a JSON Structure (such as "the first element of this array", or the entire array) and don't support wildcard expressions (such as "any/each element of this array").
This means, for example, that if you have the GET /users endpoint that returns
[
{
"id": "29d590d1-02b2-4aa1-9ce5-98202cc9a619",
"username": "nikolai",
...
},
{
"id": "58091b14-eb06-47ee-b896-50cebdda20ef",
"username": "helen",
...
},
...
]
you can define a link like $response.body#/0/id to indicate that the id of the first user in the list can be used as a parameter to another endpoint. But there's no way for a link to reference an arbitrary/each user from the list.
You can check these discussions in the OpenAPI Specification repository for more details:
Link for array element
Variables/Parameters in Links
In a Keycloak realm client, I want to aggregate the "policy" attribute defined on the users and their groups.
To test this, I have a user "joe" with the attribute "policy" set to "alpha". He is member of the group "project" that have an attribute "policy" set to "beta".
I have created a client mapper like this:
policy mapper.
But when I log into a client webapp with "joe", I've checked the JWT token sent by Keycloak and the "policy" field is set to "alpha".
I've noticed that if I change the "Token Claim Name" to "policies" (policies mapper) or "fake" for example, the JWT "policies" field is set to
"policies": [
"alpha",
"beta"
]
I don't understand why I get this behaviour and how to fix it.
By default keycloak (here version 11) provides information about the realm, a token was fetched for, only parsing the iss attribute of the token payload. e.g.
{
"exp": ...,
"iat": ...,
"jti": "...",
"iss": "http://localhost:8088/idp-provider-context/auth/realms/realmname",
"aud": [...
Is there a build in way, like a client mapper, to add the information about the realm name directly as a dedicated attribute to the JWT-token?
One workaround would be to add an attribute "realmname" to each user and setting the realmname as the value. But on the one hand this seems to be a bit messy, as it is redundant information. On the other hand this could speed up the application a bit, as tokens/users without this attribute or the wrong value in it could be already count as invalid without requesting the backend. This would identify users not created in the desired process, defined for the application.
Instead of a user attribute, use a Client Mapper Instead. For that go to:
Select your realm
Go to clients
Select the appropriate client for your use-case
(For the OLD Keycloak UI)
Go to Mappers
Click Create
In Mapper type select Hardcoded claim
Fill up the field Token Claim Name as realm name
Fill up the field Claim value as the name of the realm
Fill up the renaming fields, accordingly.
Click on Save
(For the NEW Keycloak UI)
Go to the tab Client Scopes
Click on the scope -dedicated (e.g., test-dedicated in my example)
Click on Configure a new mapper (or Add Mapper > By configuration if you have already created mappers before for this client)
Select Hardcoded claim
Fill up the field Token Claim Name as realm name
Fill up the field Claim value as the name of the realm
Fill up the renaming fields, accordingly.
Click on Save
The client will be the client that you are using to authenticate against.
So I'm using realm to cache and keep all data from our web-platform. which is loaded through an API.
When you fetch yourself as user we're also returning a user role, depending if you're a simple member, admin or whatever.
so it'd basically be
user: {
"username" : "user",
"role" : {"id":1,"name":"admin"}
}
which is cool, since realm stores this just fine in our objects which have the role as a child realmobject.
However when we load content, f/e comments. The object does not contain a role but it can contain the user which is current logged in. The data is being persisted and thus the role will be missing since it's not provided.
Are there any smart ways we could resolve this? or would the only option be to send role information with the user when comments are loaded.
If the username on User is defined as a primary key, you can use createOrUpdate / create(…, update: true) when retrieving the comments from the API to retain the user's role and merge it with the existing cached instance.
let realm = Realm()
let jsonDict = [
"message": "Hello world",
"user": [ "username" : "user" ]
]
realm.create(type: Comment.self, value: jsonDict, update: true)
Note that this works only as long as the role is missing from the retrieved JSON. If it's there as "role": null, the dictionary will contain a NSNull, which will cause that Realm nullifies the link from the user.
I can't seem to delete a GCS bucket ACL that I inserted.
I did a POST to insert an ACL for my service account:
https://www.googleapis.com/storage/v1/b/arqclient-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0s/acl
with this request JSON:
{
"entity" : "user-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0s#developer.gserviceaccount.com",
"role" : "WRITER"
}
When I list the ACLs, the ACL I inserted looks like this:
{
bucket = "arqclient-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0s";
entity = "user-00b4903a970addfce72044c71917166bd27bc8b9ab94a391dc841b526cd9466f";
entityId = 00b4903a970addfce72044c71917166bd27bc8b9ab94a391dc841b526cd9466f;
etag = "CA0=";
id = "arqclient-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0s/user-00b4903a970addfce72044c71917166bd27bc8b9ab94a391dc841b526cd9466f";
kind = "storage#bucketAccessControl";
role = WRITER;
selfLink = "https://www.googleapis.com/storage/v1/b/arqclient-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0s/acl/user-00b4903a970addfce72044c71917166bd27bc8b9ab94a391dc841b526cd9466f";
}
So apparently my "user-<emailaddress>" gets converted some other kind of ID.
When I try to delete the ACL:
DELETE https://www.googleapis.com/storage/v1/b/arqclient-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0sfkjhfkjhf/acl/user-1026650596885-sfd2omc18k3qs6lgphlch37jb5fucg0s%40developer.gserviceaccount.com
I always get a 404 error.
What's wrong with my DELETE command? The doc says I can use user-emailAddress, but that doesn't work.
If I use the entity ID from the listing, "user-00b4903a970addfce72044c71917166bd27bc8b9ab94a391dc841b526cd9466f", that works through the Google APIs Explorer.
If I'm supposed to use the entity ID, how do I get the entity ID given a service-account email address?
The access control page of the Google API docs says "You can find a user's Google Storage ID by retrieving the ACL of an object that the user uploaded." https://cloud.google.com/storage/docs/access-control?hl=en#google-storage-ids
So I guess the best answer is to create an object with my service account, retrieve its ACL, and find the entity ID in the ACL.