Remove duplication in new fangled case with patterns - ruby

This works but is ugly. But I can't find how to make optional keys in a pattern. I am probably missing somehting obvious:
post '/api/users' do
args = JSON.parse(request.body.read, {symbolize_names: true})
case args
in {name: name, email: email, bio: bio, password: password}
User.create(args)
200
in {email: email, bio: bio, password: password}
User.create(args)
200
in {email: email, password: password}
User.create(args)
200
else
400
end
end

Related

The request signature we calculated does not match the signature you provided | Aws::Sigv4::Signer | Ruby

I'm getting this error
The request signature we calculated does not match the signature you provided
The Canonical String for this request should have been
The String-to-Sign should have been
I am trying to implement the SP APIs in rails.
I've fetched the access-token from https://api.amazon.com/auth/o2/token endpoint.
And after wards created the temporary session token using Aws::STS::Client.
I used Aws::Sigv4::Signer for signature.
First Step (Access Token)
payload = {
grant_type: 'refresh_token',
client_id: [ClientId],
refresh_token: [RefreshToken],
client_secret: [ClientSecret],
}
headers = {'Content-Type': 'application/json'}
response = HTTParty.post("https://api.amazon.com/auth/o2/token", body: payload.to_json, headers: headers)
access_token = response["access_token"]
Second Step (Create Assume Role Using AWS::STS)
result = sts = Aws::STS::Client.new(
region: "us-east-1",
credentials: Aws::Credentials.new("aws-access-key", "aws-secret-key")
).assume_role({
role_arn: "role_arn",
role_session_name: 'sp-api'
})
enter code here
Third Step (Create Signature )
signer = Aws::Sigv4::Signer.new(
service: 'execute-api',
region: 'us-east-1',
# static credentials
access_key_id: access_key_id,
secret_access_key: secret_access_key,
session_token: session_token
)
signature = signer.sign_request(
http_method: 'GET',
url: 'https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID',
headers: {
'host' => 'sellingpartnerapi-na.amazon.com',
'X-Amz-Access-Token' => access_token,
})
Final Step (To call the API with the Signature Headers)
headers = {
'Content-Type' => 'application/json',
"host" => signature.headers["host"],
"X-Amz-Date" => signature.headers['x-amz-date'],
"X-Amz-Security-Token" => signature.headers["x-amz-security-token"],
"X-Amz-Content-Sha256" => signature.headers["x-amz-content-sha256"],
"Authorization" => signature.headers['authorization']
}
data = HTTParty.send(:get, "https://sellingpartnerapi-na.amazon.com/orders/v0/orders/ordersID", headers: headers)

go-swagger not calling my header check

I have an api generated through go-swagger. I am trying to put in a session check it is not firing as I expected. I followed an example that I found in github but didn't seem to work for me.
My code:
// Applies when the "X-Session-Key" header is set
api.SessionKeyHeaderAuth = func(token string) (interface{}, error) {
// test the token
success := routeHandler.HandleSessionHeaderKey(token)
if success{
return nil, nil
}
//We are pessimistic, if they aren't successful then we return a 401
api.Logger("Access attempt with incorrect api key auth: %s", token)
return nil, errors.New(401, "incorrect api key auth")
}
My Yaml (for the endpoint that I am curling):
/auth/logout:
post:
summary: Logs in the user
consumes:
- application/x-www-form-urlencoded
operationId: authLogoutUser
tags:
- auth
description:
Allow users to log out and their session will be terminated
produces:
- application/json
parameters:
- in: header
name: X-Session-Key
type: string
required: true
- in: header
name: X-Profile-Key
type: string
required: true
responses:
200:
description: Login Success
headers:
ProfileKeyHeader:
type: string
description: The key for the profile data
SessionKeyHeader:
type: string
description: The key for the session data
400:
description: Whether the user is not found or error while login, decided on a generic login failure error
schema:
$ref: 'definitions.yaml#/definitions/Error'
429:
description: Too many requests and being throttled
schema:
$ref: 'definitions.yaml#/definitions/Error'
500:
description: Too many requests and being throttled
schema:
$ref: 'definitions.yaml#/definitions/Error'
Any help to see what I did incorrectly would be appreciated.
So, I was being an idiot...
The issue was that I forgot to add Security to my swagger yaml. Once I did that then my function was getting called.
operationId: authLogoutUser
tags:
- auth
description:
Allow users to log out and their session will be terminated
produces:
- application/json
security:
- SessionKeyHeader: []

Youtube: {"error"=>"invalid_request", "error_description"=>"Required parameter is missing: grant_type"}

I am getting this error when trying to get a new refresh token:
{"error"=>"invalid_request", "error_description"=>"Required parameter
is missing: grant_type"}
Here's the code I'm using to generate the request:
HTTParty.post("https://accounts.google.com/o/oauth2/token",
{
client_id: Figaro.env.google_client_id,
client_secret: Figaro.env.google_client_secret,
refresh_token: Figaro.env.google_client_refresh_token,
grant_type: "refresh_token"
})
Despite including the grant_type param, I'm still getting the error. Any ideas why?
Discovered the answer shortly after posting:
HTTParty.post("https://accounts.google.com/o/oauth2/token",
{
:body => {
client_id: Figaro.env.google_client_id,
client_secret: Figaro.env.google_client_secret,
refresh_token: Figaro.env.google_client_refresh_token,
grant_type: "refresh_token"
}
})

Devise - Sign In with Ajax

Is here any possibility to modify devise SessionsController for ajax communication?
Edit
I found the solution, and posted it into answers, thanks
1. Generate Devise controllers so we can modify it
rails g devise:controllers
Now we have all controllers in the app/controllers/[model] directory
2. Edit routes.rb
Let's set Devise to use our modified SessionsController
First add this code (of course change :users to your devise model) into config/routes.rb
devise_for :users, controllers: {
sessions: 'users/sessions'
}
3. Modify sessions_controller.rb
Find the create method and change it to
def create
resource = User.find_for_database_authentication(email: params[:user][:email])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:user][:password])
sign_in :user, resource
return render nothing: true
end
invalid_login_attempt
end
Create new method after protected
def invalid_login_attempt
set_flash_message(:alert, :invalid)
render json: flash[:alert], status: 401
end
4. devise.rb
Insert this into config/initializers/devise.rb
config.http_authenticatable_on_xhr = false
config.navigational_formats = ["*/*", :html, :json]
5. Invalid email or password message
Insert a new message into config/locales/devise.en.yml under the sessions
invalid: "Invalid email or password."
6. View
= form_for resource, url: session_path(:user), remote: true do |f|
= f.text_field :email
= f.password_field :password
= f.label :remember_me do
Remember me
= f.check_box :remember_me
= f.submit value: 'Sign in'
:javascript
$(document).ready(function() {
//form id
$('#new_user')
.bind('ajax:success', function(evt, data, status, xhr) {
//function called on status: 200 (for ex.)
console.log('success');
})
.bind("ajax:error", function(evt, xhr, status, error) {
//function called on status: 401 or 500 (for ex.)
console.log(xhr.responseText);
});
});
Important thing remote: true
The reason why I am using status 200 or 401 unlike {status: 'true'} is less data size, so it is much faster and cleaner.
Explanation
On signing in, you get these data in params
action: "create"
commit: "Sign in"
controller: "users/sessions"
user: {
email: "test#test.cz"
password: "123"
remember_me: "0"
}
utf8: "✓"
Before signing, you need to authorize the user.
resource = User.find_for_database_authentication(email: params[:user][:email])
User.find_for_database_authentication
If user is found, resource will be filled with something like
created_at: "2015-05-29T12:48:04.000Z"
email: "test#test.cz"
id: 1
updated_at: "2015-06-13T19:56:54.000Z"
Otherwise will be
null
If the user is authenticated, we are about to validate his password
if resource.valid_password?(params[:user][:password])
And finally sign in
sign_in :user, resource
Sources
SessionsController
Helped me
Andreas Lyngstad

Ruby Shoes GUI Secret style not working

I am trying to make a login screen in Ruby Shoes. I am using the ask method to get the username and password but I want the password to show as asterisks. I have to use the secret method but I can't figure out the right syntax..
button "Login" do
username = ask("Enter Username: ")
password = ask("Enter Password: ") :secret => true
end
Should it be done this way?
password = ask("Enter Password: "), secret: true
I tried this too. It doesn't seem to work
Thanks!
Try it this way
button "Login" do
username = ask("Enter Username: ")
password = ask("Enter Password: ", :secret => true)
end

Resources