I have created bills, which should be possible to open from admin, but not as a normal user. this bill pdf will be created after certain business process in app/assets/pdfs.
assets_pdf_url if user_signed_in?
Is it possible to restrict specific assets by some rule?
Store the restricted assets in some folder outside of the public folder, so they cannot be accessed just by visiting a URL, then create an action that uses send_file or send_data. That way you can wrap it up in whatever logic you want.
# in controller
def show
#bill = Bill.find(params[:id])
if user_signed_in?
send_file Rails.root.join('bill_pdfs',"#{#bill.id}.pdf")
else
redirect_to '/', :error => "Only logged in users may download"
end
end
Related
I'm trying to create admin roles that can go in and change other users information. I've already got everything set up pretty much except that I can't get the edit method to select the correct user to update.
Looking in the devise code, it looks like I need to update the resource to be the user of the profile that's being selected instead of the current user (which would be the admin).
How do I go about updating the resource that is sent into the devise edit view and update action? It looks like it might have something to do with this
def authenticate_scope!
send(:"authenticate_#{resource_name}!", :force => true)
self.resource = send(:"current_#{resource_name}")
end
So for example, what I want to do is
def update_resource
self.resource = User.find(params[:id])
end
Is this possible?
I have set up a test applications and have setup devise to take care of the authentication, additionally I have set up a component where they are sent to a create profile page after registration which works well.
The problem I have is when a logged in user goes to edit they're profile it is easy for then to change the query string and access another users data -
http://localhost:3000/profiles/1/edit
the question i have is how do I lock this down to the current user so that can only edit they're data?
Robbie
I would go for a before_filter.
# in profiles controller
class ProfilesController < ApplicationController
before_filter :find_profile
before_filter :check_if_authorized
def find_profile
#profile = Profile.find(params[:id])
end
def check_if_authorized
render :status => 404 and return unless current_user == #profile.user
end
end
Assumptions:
devise model is named User
user has one profile
you're already checking if a user is logged in
You can use token authentication along with session for more precise and secure authentication.
Add devise :token_authenticatable to the model User
This will create an authentication token into the field authentication_token field of users table every time a user is created.
Then go for a before_filter :verify_auth_token
def verify_auth_token
if current_user.authentication_token == params[:auth_token]
return true
else
return false
end
end
Also the edit request should be http:///profiles/1/edit?auth_token=12wqaasaeaad
I have two main controllers for my app, AdminController and ApplicationController.
My proper routes are /admin/merchant/1, admin/merchant/1/shop/1 (Nested 1 level deep only =P)
However, many users will conveniently type site.url/admin or site.url/merchant out of convenience.
Is it pragmatic to match a few routes to a method in my admin controller and route them based on user? i.e. match "/admin" => "admin#route_me"
before_filter :require_login
def route_me
if current_user.role?(:merchant)
redirect_to admin_merchant_path(current_user.merchant)
elsif current_user.role? :customer
redirect_to admin_customer_path(currrent_user.customer)
end
end
Is there a good implementation out there to universally catch-all half entered routes and try to "complete" the path for them?
E.g. if the user types in admin/merchant/shops (missing merchant ID), my smart route knows he's trying to access his shop page, checks his ID and fill it up for him if he has one.
I'm trying to implement switch_user gem in my existing rails 3.0.9 application.
There are two models on my application, they are
User - for my customer accounts and it has_one Account
AdminUser - This was created by ActiveAdmin
I have already enabled devise authentication for Users and ActiveAdmin also working pretty much well with AdminUser. Now from my Active Admin interface I'd like to select the Accounts and login to those account just like the account owner does. Switch user is working fine but the problem is anyone can simply login to the user accounts now if they know the urls.
http://localhost:3000/switch_user?scope_identifier=user_1
All I need is allow only an AdminUser (i.e if there is an ActiveAdmin session) to access the User's accounts.
This is how my /config/initializers/switch_user.rb looks like
SwitchUser.setup do |config|
config.controller_guard = lambda { |current_user, request| current_admin_user.nil?}
config.redirect_path = lambda { |request, params| "/dashboard" }
end
But I get this error
NameError in SwitchUserController#set_current_user
undefined local variable or method `current_admin_user' for main:Object
Is there anyway I can access the active admin session?
Code for /config/initializers/active_admin.rb
ActiveAdmin.setup do |config|
config.site_title = "MyAppName"
config.authentication_method = :authenticate_admin_user!
config.current_user_method = :current_admin_user
end
btw in my application controller I haven't created any methods for authenticate_admin_user , current_admin_user active admin works fine without them.
You need modify local config/initializers/switch_user.rb:
config.controller_guard = lambda { |current_user, request, original_user, controller|
controller.admin_user_signed_in?
}
Original lambda has 2 arguments.
Just append more (up to 4) and use it.
Don't forget restart rails server :)
OK I think I found a solution to secure the switch_user. All I did is moving the routes inside the admin_users scope
ActiveAdmin.routes(self)
devise_for :admin_users, ActiveAdmin::Devise.config do
match '/admin/switch_user', :controller => 'switch_user', :action => 'set_current_user'
end
I'm trying to understand the models and the relations I need to have in order to let users register and choose a subdomain. I'm thinking in having an Account model and a User model using Devise as an authentication system. Being that the user belongs to an Account and an Account has_many Users.
Not sure if this is the best schema to accomplish what I want but, given what I've written, I'm struggling to understand how to make the e-mail unique for the Subdomain and only allow to login when in the subdomain. The Admin will then be able to invite other users to his account.
Is there a better way to do this?
Thanks
Donald
Most of the work can be done in routes.rb:
module AppName
class UserSubdomainConstraint
def self.matches?( request )
request.subdomain.present? && request.subdomain != 'www'
end
end
end
AppName::Application.routes.draw do
devise_for :users
# THESE ARE THE ROUTES FOR YOUR MAIN SITE
constraints( AppName::UserSubdomainConstraint ) do
# THESE ARE THE ROUTES FOR USERS' SUBDOMAINS
end
end
Then you can identify the user using the request.subdomain in your controller:
def index
#user_account = User.where( :subdomain => request.subdomain ).account
end
Devise logins are going to be global across all sub-domains correct? So you can pretty much treat them as you would in any other app.