Devise Responding With 422 On Sign Up of User - ruby-on-rails

Not sure why this is happening..I'm running against route /users.json and passing in the body as:
{
"email": "register#register.com",
"password": "ssssssssss"
}
I'm getting back: {"errors":{"email":["can't be blank"],"password":["can't be blank"]}}
uhmmm...what?

If you didn't change your controllers from the default scaffolds, the body should have "user" as the root key:
{
"user": {
"email": "register#register.com",
"password": "ssssssssss"
}
}
Also check your server logs that the parameters are actually accepted and parsed correctly.

Rolling back to version 3.3.2 of Devise fixed...and using #Ivan's req body of:
{
"user": {
"email": "register#register.com",
"password": "ssssssssss"
}
}

Related

Request sent from Swagger UI not resulting in Postman x-www-form-urlencoded response

I'm currently configuring a Swagger file to utilize OAuth to retrieve tokens from a site. For brevity, I have removed my schemes and most of my paths as those are fine.
{
"openapi": "3.0.2",
"info": {
"title": "swagger",
"version": "1.0.0",
"description": ""
},
"servers": [
{
"url": "url"
}
],
"paths": {
"/oauth_token.do": {
"post": {
"requestBody": {
"required": true,
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"type": "object"
}
}
}
}
}
}
},
"components": {
"securitySchemes": {
"OAuth": {
"type": "oauth2",
"flows": {
"password": {
"tokenUrl": "/oauth_token.do",
"refreshUrl": "/oauth_token.do",
"scopes": {
"useraccount": "utilize user account"
}
}
}
}
}
}
"security": [
{
"OAuth": ["useraccount"]
}
]
}
The endpoint for this API specifies that I should use x-www-form-urlencoded in the header as the Content-Type. When executing this request in Postman, it returns 200 with the desired response.
However, with https://editor.swagger.io I input the same postman request to get the fetch failed error with my Authorize button. To test for this, I created a custom path that specifies that the content should be x-www-form-urlencoded and this also fails.
So, what am I missing in this case? Any help would be appreciated.
I believe the issue was I did not fill out some portions I added on the response for path. Instead I opted to only leave description for the 200 response.
The main error I'm getting now is CORS related which is unrelated to the original question. I'll mark this answered for now.

Apache Ranger REST API addUsersAndGroups returns 404 not found

We have installed Apache Ranger and the Web UI works fine, most of the REST API method works fine on both PublicAPIsv2 and RoleREST as per https://ranger.apache.org/apidocs/ui/index.html.
I can get “test_role” id by calling GET /public/v2/api/roles/name/test_role which returns the id 409.
I can get test_role content by calling GET /public/v2/api/roles/409
I can change test_role users list by editing the response I get from GET /public/v2/api/roles/409 and submitting it through PUT /public/v2/api/roles/409
The body is:
{
"id": 409,
"isEnabled": true,
"createdBy": "admin",
"updatedBy": "admin",
"createTime": 1598241102841,
"updateTime": 1601975068428,
"name": "test_role",
"options": {},
"users": [
{
"name": "test_user1”,
"isAdmin": true
},
{
"name": “test_user2”,
"isAdmin": true
},
{
"name": “test_user3”,
"isAdmin": false
}
],
"groups": [
{
"name": "test_group”,
"isAdmin": false
}
],
"roles": []
}
But calling PUT /public/v2/api/roles/409/addUsersAndGroups returns “404 not found”.
I tried with the same body as above as parameter, and also with:
{
"users": [
{
"name": “test_user4”,
"isAdmin": true
}
]
}
Would anybody know what is the correct body to send as parameter to:
/public/v2/api/roles/409/addUsersAndGroups?
Also, making a wrong call such as GET /public/v2/api/roles/409/addUsersAndGroups returns “405 method not allowed”. So I believe it shows the end point does exist. I’m not sure why calling PUT public/v2/api/roles/409/addUsersAndGroups with (probably) incorrect body returns “404 not found” and not an error message related to the wrong parameter.
It happens because Apache Ranger API documentation is wrong, remove the suffix /addUsersAndGroups of your endpoint and it will work.
Example: https://ranger_url/service/roles/roles/409
Where 409 is the role ID, as you're using on your example.
The body that is needed:
{
"name": "test_role",
"users": [
{
"name": "test_user1",
"isAdmin": true
}
]
}

Nested parameters on GET request

Question of the day: how to encode URL to be able to pass complex data on a GET request?
# data to pass
{
"main_key": {
"other_key": {
"main_array": [{
"name": "Bob",
"nickname": "bobby"
},
{
"name": "Tom",
"nickname": "Tommy"
}
]
}
}
}
Here is the current solution I got with Postman
Here is the current Rails interpretation of such a query, which is correct.
# Rails server side
Parameters: {"main_key"=>{"other_key"=>{"main_array"=>[{"name"=>"Bob", "nickname"=>"bobby"}, {"name"=>"Tom", "nickname"=>"tommy"}]}}, "default"=>{"format"=>:json}}
Can anybody have a better way to achieve a request with such a complex nested array object?
The other solution I got is to pass JSON directly as value of a query parameter and then parse it from the controller.
**Edit: ** I can pass this json on the body of the request but as it's a GET method, it does not respect XHR requirements.
If you have jquery, you can use .param() method of it.
let myParams = {
"main_key": {
"other_key": {
"main_array": [{
"name": "Bob",
"nickname": "bobby"
},
{
"name": "Tom",
"nickname": "Tommy"
}
]
}
}
}
console.log($.param(myParams));
This will give you your desired string.
"main_key%5Bother_key%5D%5Bmain_array%5D%5B0%5D%5Bname%5D=Bob&main_key%5Bother_key%5D%5Bmain_array%5D%5B0%5D%5Bnickname%5D=bobby&main_key%5Bother_key%5D%5Bmain_array%5D%5B1%5D%5Bname%5D=Tom&main_key%5Bother_key%5D%5Bmain_array%5D%5B1%5D%5Bnickname%5D=Tommy"

Why should POST data be nested?

I am using Rails as an API server, and I wonder why the data being sent to the server needs to be nested. This seems to be the preferred way of defining params:
def user_params
params.require(:user).permit(:first_name, :last_name, :password, :username, :email)
end
And this would be the corresponding JSON sent to the create route:
{
"user": {
"username": "lorem",
"first_name": "ipsum",
"last_name": "dolor",
"password": "sit",
"email": "amet"
}
}
Why is this the preferred way of posting data? Why could not the JSON be:
{
"username": "lorem",
"first_name": "ipsum",
"last_name": "dolor",
"password": "sit",
"email": "amet"
}
These aren't the only parameters that are sent while creating a resource for you, others are:
utf8 with value ✓
authenticity_token with a random string
commit with value either Save or Update
So the logic is pretty obvious: Rails groups all the user-belonging-parameters inside user key, and thus, it's easier to read, easier to interpret by the code, and easier to whitelist the related parameters.
Not only this, sometimes you will try to create multiple resources through one request, like a user has many books, so you would like to create a user, and at the same time, books - something called Nested Resources, and in that case, it will be like this:
{
"user":
{
"username": "john_don",
"books":
{
"0":
{
"author_id": 1
}
}
}
}
I hope you get the idea.

Change response required for Rails authentication

I've a user model and a login route. Using ember-simple-auth, whenever I'm sending the data for authentication, the data is required to be in this format:
{"password"=>"[FILTERED]", "email"=>"admin#admin.com"}
However, I want the data to be in this format:
{"user"=>{"password"=>"[FILTERED]", "email"=>"admin#admin.com"}}
How can I change this?
Thanks.
Code: https://github.com/ghoshnirmalya/hub-server
As a possible approach you can override resoure_params method
class Api::V1::SessionsController < DeviseTokenAuth::SessionsController
private
def resource_params
params.permit(user: params_for_resource(:sign_in))[:user]
end
end
routes
namespace "api" do
namespace "v1" do
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
sessions: 'api/v1/sessions'
}
resources :users
end
end
Then if your params looks like
{
"user": {
"email": "nirmalya.email#gmail.com",
"password":"password"
}
}
you will receive success response:
{
"data": {
"id": 1,
"provider": "email",
"uid": "nirmalya.email#gmail.com",
"name": "Nirmalya Ghosh",
"nickname": null,
"image": null,
"email": "nirmalya.email#gmail.com"
}
}
But I'm strongly recommend to refactor your frontend to meet devise_token_auth reqirements and pass params as {email: "foo#mail.com", password: "password"}

Resources