Ruby on Rails - Session in Model for External API - ruby

I have an app without models or any database connectivity.
I have a method defined in the ApplicationController called "api_call" which does all api calls within the app. This method uses the ruby session to store things about the user, such as authentication info, access token info, and user info. In the session I store an Authentication hash for sending to the api for security when the user is logged.
Two things:
I'd like to put all api calls (the api_call method) in models (that don't use db or validation), but the problem is I don't have access session.
If I use a module, the module in the model also doesn't have access to the session.
If I create a model class without using ActiveRecord, should I use class methods rather than object methods?

How about passing the "authentication hash" to the API model's constructor?
class Api
def initialize auth
#auth = auth
end
end
class FooController < ApplicationController
def index
api = Api.new session[:auth]
end
end
Also, if you haven't see Pratik Naik's article about this, it's pretty funny.

Related

DRF - making api available only to known clients

I have a DRF api which does not have any authentication system (because the concept of a user is meaningless there). And yet I want to make the api be restricted only to known clients. In other words, I want to come up with an api-to-api authentication rather than user-to-api authentication. Is that possible in DRF ? And are there any ready-to-use libs out there ?
You can use a permission class for it. Define a permission class that inherited from permissions.BasePermission
from rest_framework import permissions
class SamplePermission(permissions.BasePermission):
def has_permission(self, request, view):
return request.META.get('HTTP_YOUR_KEY','') in ['some_key']
and define it inside your view as permission_classes
class SampleViewSet(views.APIView):
...
permission_classes = [SamplePermission]
I can't say this is the best way but you can use it with this.

Rails 5 Using Devise and acts_as_tenant

I have an application that's using Devise to handle sign in/registration. I'm also using acts_as_tenant. I need to ensure a Tenant is set every time someone goes to register/sign in. For acts as tenant to work, the tenant must be set prior to authentication. Right now I'm using a before_action on my ApplicationController but the issue is that method gets called even if someone has invalid credentials etc, and I'm trying to avoid having to write if statements in the method to figure out if I have a valid user or not.
What is the best way to achieve this? Anyone in a similar situation?
If you need to set your tenant before authenticating with Devise, you need to use acts_as_tenant's manual tenant setting method so that you can control the timing.
# application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
# tell acts_as_tenant you'll manually set the tenant
set_current_tenant_through_filter
# manually set the tenant before Devise auth
prepend_before_action :set_current_tenant_by_subdomain
# Devise auth as usual but after tenant is set
before_action :authenticate_user!
private
def set_current_tenant_by_subdomain
current_organization = Organization.find_by_subdomain(request.subdomain)
set_current_tenant(current_organization)
end
end

Unable to store session data into cookie and send back to server

Currently, I am working on signup functionality of a web application using Rails 4. Basically, the working flow will be as follow:
User fills in signup form and submit it to server
Signup request then will be handled by create method of UserController
Session data will be then stored in cookie and sent back to server to persist session data among requests.
However, when observing response header after trying to signup, I did not see set-cookie property. And, in fact, current cookies does not store any session data for server to realize session. Below is my code:
users_controller.rb
class UsersController < ApplicationController
...
def create
#user = User.create(user_params)
# set session
log_in #user
render 'index'
end
...
end
application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :null_session
include SessionHelper
end
session_helper.rb
module SessionHelper
# Log in a given user
def log_in(user)
# Send session stored in a temporary cookie to browser
# By default, cookie will be storage mechanism for session
session[:user_id] = user.id
end
I will be thankful if someone can explain the root of problem and give me some workarounds.
Have you tried without the parameter with: :null_session in application_controller?
everyone.
After having done some research, I had found out a workaround by adding skip_before_action :verify_authenticity_token in UserController to bypass authenticity_token as follow:
class UsersController < ApplicationController
# To make the sesson get reset
skip_before_action :verify_authenticity_token
end
Thank you so much for your attention.
Regards.

Ruby: protect_from_forgery when is it raised?

I have the following piece of code:
class Foo < ActiveRecord::Base
protect_from_forgery
end
My doubt is when the protect_from_forgery will be called? when an instance of Foo is created?
Thanks in advance
Someone with more knowledge than myself might know a better answer but here is how I understand it:
When the browser sends a post request, rails includes an additional authenticity token with the requests that corresponds to that users session. If I knew another users authenticity token, I could add an html element on the page that includes their token and submit requests posing as their user. This is called Cross Site Request Forgery. To protect your site from such attacks, rails includes a method called protect_from_forgery. This method should be placed at the top of your Application Controller so check each request for authenticity.
Further reading can be found on the Rails Guide to Security.

rails role based access using cancan

There is no user and roles table. I have a tabless model for users and roles. user information is set in the application controller with the values from the environmental variables, for this one I have hard coded the value. The role information comes from the service.
#Application controller setting the user object
before_filter :set_user
def set_user
#user = User.new(:id => 123)
end
I am using cancan for authorization and ability.rb doesnt see this #user or user and comes in as nil.Does ability load before the application controller? Am I missing anything in the controllers for cancan? I have load_and_authorize_resource in the controllers.
Any suggestion will be greatly helpful.
Thanks
Ramya
Add this method in your ApplicationController if you don't have it:
def current_user
#user
end

Resources