Update a model data using PUT - rest

I have a user model, I am providing a RESTful API so the client can call to update the necessary data for a given user. The following is the code and also the curl command that I used to update the user data, but it didn't work anyhow. Is there anything wrong with my code/command?
And I have the following route setup
PUT /user/{<\d+>id}/? Users.update
// Updates a single user.
public static void update(Long id) {
// Fetch from user from DB
User user = safeFindById(id);
// Set new values
user.edit("user", params.all());
// Persist user
user.validateAndSave();
// return the user rendered based on template
get(id);
}
Using Curl - add a new user
$ curl d '{"email":"admin#foo.com","password":"secret","firstname":"who","lastname":"is"}' -X POST http://localhost:9001/user/add
To update the user, both commands below didn't work
$ curl -H "Accept: application/json" -X PUT -d "firstname=test" http://localhost:9001/user/1
$ curl -H "Accept: application/json" -H "X-HTTP-Method-Override: PUT" -X POST -d "firstname=test" http://localhost:9001/user/1

Well without the complete route and a exception is difficult to analyze the problem. Furthermore I can't know how if your User-Object hast really a firstname and not a firstName. I would recommend to change the method:
public static void update(Long id, String firstname) {
Logger.error(firstname);
....
}
So you could check if the error was in the request.

Related

Getting 404 error in Rest Api guest-cart. [GET] V1/guest-carts/{cart-id}

I am trying to get my created guest cart through the REST api after i create it with POST /guest-cart/ and use the returned ID.
when i try to get the created cart with
/rest/all/V1/guest-carts/{Cart-id}
It returns a 404 error
{ "message": "No such entity with %fieldName = %fieldValue", "parameters": { "fieldName": "cartId", "fieldValue": null },
This is also true when i try it with swagger
curl -X GET "http://website.com/default/rest/all/V1/guest-carts/{cart-id}" -H "accept: application/json" -H "Authorization: Bearer {token}"
in both cases I send it with the Authorization and content-type header
I tried making the call in Swagger and Postman
I expect to recieve an empty Guest-cart
See if you can get a response from the items call using GET - in your case, the response should have no items.
/V1/guest-carts/{cartId}/items
If this doesnt work, you may have other issues. Cart ID typically expires after 1 hour, so get a new Cart ID for this and future tests. Look into your Magento logs to see if any errors show up with additional info.

How to get users by custom attributes in keycloak?

I know that there is admin APIs to get the list of users which returns the user representation array.
GET /admin/realms/{realm}/groups/{id}/members
returns
https://www.keycloak.org/docs-api/2.5/rest-api/index.html#_userrepresentation
but is there a way to get users by custom attribute ?
This is not possible by default, but Keycloak offers the possibility to extend its functionalities via a system of Service Provider Interfaces which is very easy to implement.
Here is an example of new route that allows to search by custom attributes :
public class SearchByAttributeResourceProvider implements RealmResourceProvider {
private KeycloakSession session;
public SearchByAttributeResourceProvider(KeycloakSession session) {
this.session = session;
}
#Override
public Object getResource() {
return this;
}
#GET
#Path("search-by-stuff/{stuffValue}")
#Produces({MediaType.APPLICATION_JSON})
public List<UserRepresentation> getUsersByStuff(#PathParam("stuffValue") String stuffValue) {
return session
.users()
.searchForUserByUserAttribute("stuff", stuffValue, session.getContext().getRealm())
.stream()
.map(userModel -> ModelToRepresentation.toRepresentation(session, session.getContext().getRealm(), userModel))
.collect(toList());
}
#Override
public void close() {
}
}
You'll find more details here : https://www.keycloak.org/docs/latest/server_development/index.html#_extensions_rest
This is enabled out of the box from Keycloak version 15.1.0
Using GET /{realm}/users API, parameter q is introduced: A query to search for custom attributes, in the format 'key1:value2 key2:value2'
curl 'http://{{keycloak_url}}/auth/admin/realms/{{realm}}/users?q=phone:123456789'
You can also combine several attributes within this parameter using space ' ' delimiter
curl 'http://{{keycloak_url}}/auth/admin/realms/{{realm}}/users?q=phone:123456789 country:USA'
Docs: https://www.keycloak.org/docs-api/15.1/rest-api/index.html#_users_resource
With latest version of keycloak (18.01), we have api in
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
List<UserRepresentation> searchByAttributes(#QueryParam("q") String searchQuery);
The query param is of format 'key:value' . Using this we can get list of all users by custom attributes
Update: The /auth path was removed starting with Keycloak 17 Quarkus distribution. So you might need to remove the /auth from the endpoint calls presented on this answer.
Keycloak versions from 15.1.0 upwards
Although not mentioned on the release notes it is possible after Keycloak version 15.1.0 (as pointed out by #Darko) to search users by custom attributes, introduced with this commit. As one can now see on the GET /{realm}/users endpoint of the Keycloak Admin Rest API:
Form example:
curl 'https://${KEYCLOAL_HOST}/auth/admin/realms/${REALM_NAME}/users?q=employeeNumber:444555'
Keycloak versions before 15.1.0
For version before 15.1.0, out-of-the-box you can use the Keycloak Admin API endpoint:
GET /{realm}/users
one can read that :
Get users Returns a list of users, filtered according to query
parameters
those (optional) query parameters being:
briefRepresentation (boolean);
email (string);
first (string);
firstName (string);
lastName (string);
max (Maximum results size (defaults to 100)) (integer);
search (A String contained in username, first or last name, or email);
username (string).
As you can see you cannot search for custom attributes. A not so great solution is to get all the users (max=-1), and filter afterwards by the custom attribute.
The other option (pointed out by #Lucas) is to extend Keycloak functionality by adding your own custom Service Provider Interfaces (SPI) and adding your custom endpoint. There you can take advantage of the searchForUserByUserAttribute method from the UserQueryProvider interface.
Step-by-step with Keycloak Admin API versions from 15.1.0 upwards
To use the Keycloak Admin REST API, you need an access token from a user with the proper permissions. For now, I will be using the admin user from the master realm, and later explain how to use another user:
curl “https://${KEYCLOAK_HOST}/auth/realms/master/protocol/openid-connect/token” \
-d "client_id=admin-cli" \
-d "username=${ADMIN_NAME}” \
-d "password=${ADMIN_PASSWORD}" \
-d "grant_type=password"
You get a JSON response with the admin's token. Extract the value of property access_token from that response. Let us save it in the variable $ACCESS_TOKEN for later reference.
To get the list of users from your realm $REALM_NAME with a given set of attributes (i.e., ${ATTRIBUTES}).
curl -X GET “https://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/users?q=${ATTRIBUTES}” \
-H "Content-Type: application/json" \
-H "Authorization: bearer ${ACCESS_TOKEN}”
I have the aforementioned steps coded in the script getUserByAttributes.sh on my GitHub repo for those that are interested. An example :
sh getUserByAttributes.sh localhost:8080 admin admin test_realm 'employeeNumber:4445 something:a'
Assigning the proper user permissions
For those that do not want to get an access token from the master admin user, you can get it from another user but that user needs the permission manage-users from the realm-management client. For that you can check this answer on how to do it
Current Keycloak API version is 4.8 and there is API:
Get users Returns a list of users, filtered according to query parameters
GET /{realm}/users
See doc: https://www.keycloak.org/docs-api/4.8/rest-api/index.html#_users_resource
Only this "search" is available from the API. If you need search by user attributes, then you need to implement it in your own code.
You can filter keycloak users using their custom attributes by passing the 'q' get parameter:
IN SUMMARY:
<get-users-url>?q=key1:value1 key2:value2
EXAMPLE:
curl --location --request GET 'http://localhost:8080/admin/realms/realm-name/users?q=key1:value1 key2:value2' \
--header 'Authorization: Bearer <your-token>'

Get ALL worklog from Jira REST API

is there a working REST curl to get all worklog of every issue there is,
I ve tried POST /rest/api/2/worklog/list , but I dont have a list of worklog ids !!
and I don't wanna go through issues either
you can try this POST API : /rest/tempo-timesheets/4/worklogs/search which required few request body params as : {"from":"2018-11-01","to":"2018-11-30","epicKey":["epic-key1"],"projectKey":["project-key1"]}.
If you do not want to go through all the issues, you can get the worklog IDs via Get ids of worklogs modified since REST API. The response body will contain the IDs you can use for /rest/api/2/worklog/list.
You will have to go through issues. The fastest way is to execute a search with JQL query: worklogDate > 0 that will return all the issues that have any worklogs. Then you will have to ask for worklogs of each returned issue.
Both resources, search results and worklogs of issue are paginated resources so you will have to iterate to get all the worklogs of all the issues (unless you have a small instance).
IDS=$(echo {1001..2000} | tr ' ' ',') && curl \
-u username:password \
-X POST \
--data '{"ids":['$IDS']}' \
-H "Content-Type: application/json" https://jira.com/rest/api/2/worklog/list

In Spring data rest is possible to add nested #OneToMany object to parent over POST /parent/{parentId}/nested?

I have Parent and Nested objects. I can get list of nested, using GET /parent/{parentId}/nested but I cannot POST/PUT to it with success. On POST result I get HTTP 204 and parent have empty list of nested objects.
In logs I see that Hibernate do not insert anything in DB.
During debugging I see that Jackson Object Mapper for deserealization getting "org.springframework.hateoas.Resources<java.lang.Object>" as JavaType.
Here is real example of my POST:
curl 'http://localhost:8000/api/users/402880e554b8f7960154b8f7adbc0000/orders/' -i -X POST -H 'Authorization: Basic OLOLO==' -H 'Accept: application/json' -H 'deviceCurrencyCode: USD' -H 'Content-Type: application/json; charset=UTF-8' -d '{"orderPrice": 0,"tax": 0,"shippingCost": 0,"credits": 0,"addresses": [{"firstName": "Figli","lastName": "Migli","zipCode": "5555","city": "Riga","country": "Tlmltr","phone": "7777","address": "Adddr"}],"status": "status"}'
I know that it is possible to do POST /nested '{"parent":"/link/to/parent"}'. But if it is way to GET nested objects over parent, why I cannot POST/PUT/PATCH them this way? I checked, is it RESTfull, and seems it is.
There is a a section "The association resource" in the spring data rest documentation that tells you what is possible on this resource. And creating a new child and associating it is not possible.
I do not know the why this is.
The only way (I know of) to get this behaviour is to implement a custom controller that does that for you. (Make sure you do not use the #RequestMapping annotation on class level on your custom controller to not override more spring data rest functionality than you want to)

Getting users information from moodle

How to get the section's user information (like name, password)? Is there any method that returns it?
I'm trying the function "core_user_get_users_by_field", but it isn't works. That's I've done:
String serverurl = url + "/webservice/rest/server.php" + "?wstoken=" + token + "&wsfunction=" + functionName;
obs: The server was constructed using REST.
This works for me
/webservice/rest/server.php?wstoken=xxx&wsfunction=core_user_get_users_by_field&field=id&values[0]=2
2 is the user id.
You can use any field that uniquely identifies the user. eg: field=username
You can also retrieve more than one user at a time eg: values[0]=2&values[1]=3
This is assuming the function was added as a web service following these instructions
http://docs.moodle.org/25/en/Using_web_services
There is global object called $USER in moodle, this object contains all information about user, So where you want these information just access like,
global $USER; // <= don't forget to write this before to access
$USER->username;
$USER->firstname;
$USER->lastname;
$USER->password;
Its works with:
https://url.moodle.xyz/webservice/rest/server.php?wstoken=XXXXXXX&wsfunction=core_user_get_users_by_field&field=id&values%5B0%5D=1306
The query parameters:
wsfunction=core_user_get_users_by_field
field=id
values[0]=1234
values[0] is user id.
To get moodle userdetails based on user name you can use like this :
/webservice/rest/server.php?wstoken=8888&wsfunction=core_user_get_users_by_field&field=username&values[0]=mark
To get JSON data Use :
/webservice/rest/server.php?wstoken=8888&wsfunction=core_user_get_users_by_field&field=username&values[0]=mark&moodlewsrestformat=json
Via curl POST request:
curl \
-X POST \
--data-urlencode "wstoken=123456789..." \
--data-urlencode "wsfunction=core_user_get_users_by_field" \
--data-urlencode "field=id" \
--data-urlencode "values[0]=123456" \
https://moodle.domain.tld/webservice/rest/server.php
As Russell England said:
[...] use any field that uniquely identifies the user. eg: field=username