-
-
Save AriefLuthfi79/fe8e5b9341594e1b0f3dfc7b2936023c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions/admin_permission.rb | |
module Permissions | |
class AdminPermission < BasePermission | |
def initialize(user) | |
allow_all | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/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: :exception | |
# include SessionsHelper | |
before_filter :check_authorization | |
delegate :allow_action?, to: :current_permission | |
helper_method :allow_action? | |
delegate :allow_attribute?, to: :current_permission | |
helper_method :allow_attribute? | |
private | |
def current_permission | |
@current_permission ||= Permissions.permission_for(current_user) | |
end | |
def current_resource | |
nil | |
end | |
def check_authorization | |
if current_permission.allow_action?(params[:controller], params[:action], current_resource) | |
current_permission.permit_params! params | |
else | |
redirect_to root_url, alert: "Not Authorized." | |
end | |
end | |
def current_user | |
# @current_user ||= User.find(session[:user_id]) if session[:user_id] | |
@current_user ||= User.find_by_auth_token(cookies[:auth_token]) if cookies[:auth_token] | |
end | |
helper_method :current_user | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions/base_permission.rb | |
module Permissions | |
class BasePermission | |
def allow_action?(controller, action, resource = nil) | |
allowed = @allow_all || @allowed_actions[[controller.to_s, action.to_s]] | |
allowed && (allowed == true || resource && allowed.call(resource)) | |
end | |
def allow_all | |
@allow_all = true | |
end | |
def allow_action(controllers, actions, &block) | |
@allowed_actions ||= {} | |
Array(controllers).each do |controller| | |
Array(actions).each do |action| | |
@allowed_actions[[controller.to_s, action.to_s]] = block || true | |
end | |
end | |
end | |
def allow_attribute(resources, attributes) | |
@allowed_params ||= {} | |
Array(resources).each do |resource| | |
@allowed_params[resource] ||= [] | |
@allowed_params[resource] += Array(attributes) | |
end | |
end | |
def allow_attribute?(resource, attribute) | |
if @allow_all | |
true | |
elsif @allowed_params && @allowed_params[resource] | |
@allowed_params[resource].include? attribute | |
end | |
end | |
def permit_params!(params) | |
if @allow_all | |
params.permit! | |
elsif @allowed_params | |
@allowed_params.each do |resource, attributes| | |
if params[resource].respond_to? :permit | |
params[resource] = params[resource].permit(*attributes) | |
end | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions/captain_permission.rb | |
module Permissions | |
class CaptainPermission < BasePermission | |
def initialize(user) | |
allow_action :users, [:new, :create, :edit, :update] | |
allow_action :sessions, [:new, :create, :destroy] | |
allow_action :password_resets, [:new, :create, :edit, :update] | |
allow_action :pages, [:show] | |
allow_action :ranks, [:index, :show] | |
allow_action :precepts, [:index, :show] | |
allow_action :bulletins, [:index, :show, :new, :create, :edit, :update, :destroy] | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions/guest_permission.rb | |
module Permissions | |
class GuestPermission < BasePermission | |
def initialize(user) | |
allow_action :users, [:new, :create] | |
allow_action :sessions, [:new, :create, :destroy] | |
allow_action :password_resets, [:new, :create, :edit, :update] | |
allow_action :pages, [:show] | |
allow_action :ranks, [:index, :show] | |
allow_action :precepts, [:index, :show] | |
allow_action :bulletins, [:index, :show] | |
end | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions.rb | |
module Permissions | |
def self.permission_for(user) | |
if user.nil? | |
VisitorPermission.new | |
elsif user.roles.include? "admin" | |
AdminPermisson.new(user) | |
elsif user.roles.include? "captain" | |
CaptainPermission.new(user) | |
elsif user.roles.include? "student" | |
StudentPermission.new(user) | |
# elsif user.roles.include? "guest" | |
else | |
GuestPermission.new(user) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/ranks_controller.rb | |
class RanksController < ApplicationController | |
# before_action :set_rank, only: [:show, :edit, :update, :destroy] | |
# GET /ranks | |
# GET /ranks.json | |
def index | |
@ranks = Rank.all | |
end | |
# GET /ranks/1 | |
# GET /ranks/1.json | |
def show | |
@rank = current_resource | |
end | |
# GET /ranks/new | |
def new | |
@rank = Rank.new | |
end | |
# GET /ranks/1/edit | |
def edit | |
@rank = current_resource | |
end | |
# POST /ranks | |
# POST /ranks.json | |
def create | |
@rank = Rank.new(rank_params) | |
respond_to do |format| | |
if @rank.save | |
format.html { redirect_to @rank, notice: 'Rank was successfully created.' } | |
format.json { render :show, status: :created, location: @rank } | |
else | |
format.html { render :new } | |
format.json { render json: @rank.errors, status: :unprocessable_entity } | |
end | |
end | |
end | |
# PATCH/PUT /ranks/1 | |
# PATCH/PUT /ranks/1.json | |
def update | |
@rank = current_resource | |
respond_to do |format| | |
if @rank.update(rank_params) | |
format.html { redirect_to @rank, notice: 'Rank was successfully updated.' } | |
format.json { render :show, status: :ok, location: @rank } | |
else | |
format.html { render :edit } | |
format.json { render json: @rank.errors, status: :unprocessable_entity } | |
end | |
end | |
end | |
# DELETE /ranks/1 | |
# DELETE /ranks/1.json | |
def destroy | |
@rank = current_resource | |
@rank.destroy | |
respond_to do |format| | |
format.html { redirect_to ranks_url, notice: 'Rank was successfully destroyed.' } | |
format.json { head :no_content } | |
end | |
end | |
private | |
# Use callbacks to share common setup or constraints between actions. | |
def set_rank | |
@rank = Rank.find(params[:id]) | |
end | |
def current_resource | |
@current_resource ||= Rank.find(params[:id]) if params[:id] | |
end | |
# Never trust parameters from the scary internet, only allow the white list through. | |
def rank_params | |
params.require(:rank).permit(:name, :belt, :traditional) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# spec/controllers/ranks_controller_spec.rb | |
require 'rails_helper' | |
# This spec was generated by rspec-rails when you ran the scaffold generator. | |
# It demonstrates how one might use RSpec to specify the controller code that | |
# was generated by Rails when you ran the scaffold generator. | |
# | |
# It assumes that the implementation code is generated by the rails scaffold | |
# generator. If you are using any extension libraries to generate different | |
# controller code, this generated spec may or may not pass. | |
# | |
# It only uses APIs available in rails and/or rspec-rails. There are a number | |
# of tools you can use to make these specs even more expressive, but we're | |
# sticking to rails and rspec-rails APIs to keep things simple and stable. | |
# | |
# Compared to earlier versions of this generator, there is very limited use of | |
# stubs and message expectations in this spec. Stubs are only used when there | |
# is no simpler way to get a handle on the object needed for the example. | |
# Message expectations are only used when there is no simpler way to specify | |
# that an instance is receiving a specific message. | |
RSpec.describe RanksController, type: :controller do | |
it { should be_a ApplicationController } | |
# it "should have a current_user" do | |
# login_admin | |
# expect(subject.current_user).to_not eq(nil) | |
# end | |
# | |
# it "should get index" do | |
# login_admin | |
# get 'index' | |
# expect(response).to be_success | |
# end | |
let(:admin_user) { create(:admin) } | |
# let(:user) { create(:user) } | |
# This should return the minimal set of attributes required to create a valid | |
# Rank. As you add validations to Rank, be sure to | |
# adjust the attributes here as well. | |
let(:valid_attributes) { | |
{ | |
:name => "aShodan", | |
:belt => "Black Belt", | |
:traditional => 'Black Belt' | |
} | |
} | |
let(:invalid_attributes) { | |
{ | |
:name => nil, | |
:belt => "Black Belt", | |
:traditional => 'Black Belt' | |
} | |
} | |
# This should return the minimal set of values that should be in the session | |
# in order to pass any filters (e.g. authentication) defined in | |
# RanksController. Be sure to keep this updated too. | |
let(:valid_session) { { cookies[:auth_token] => admin_user.auth_token } } | |
describe "GET #index" do | |
it "assigns all ranks as @ranks" do | |
rank = Rank.create! valid_attributes | |
get :index, {}, valid_session | |
expect(assigns(:ranks)).to eq([rank]) | |
end | |
end | |
describe "GET #show" do | |
it "assigns the requested rank as @rank" do | |
rank = Rank.create! valid_attributes | |
get :show, {:id => rank.to_param}, valid_session | |
expect(assigns(:rank)).to eq(rank) | |
end | |
end | |
describe "GET #new" do | |
it "assigns a new rank as @rank" do | |
get :new, {} | |
expect(assigns(:rank)).to be_a_new(Rank) | |
end | |
end | |
describe "GET #edit" do | |
it "assigns the requested rank as @rank" do | |
rank = Rank.create! valid_attributes | |
get :edit, {:id => rank.to_param}, valid_session | |
expect(assigns(:rank)).to eq(rank) | |
end | |
end | |
describe "POST #create" do | |
context "with valid params" do | |
it "creates a new Rank" do | |
expect { | |
post :create, {:rank => valid_attributes}, valid_session | |
}.to change(Rank, :count).by(1) | |
end | |
it "assigns a newly created rank as @rank" do | |
post :create, {:rank => valid_attributes}, valid_session | |
expect(assigns(:rank)).to be_a(Rank) | |
expect(assigns(:rank)).to be_persisted | |
end | |
it "redirects to the created rank" do | |
post :create, {:rank => valid_attributes}, valid_session | |
expect(response).to redirect_to(Rank.last) | |
end | |
end | |
context "with invalid params" do | |
it "assigns a newly created but unsaved rank as @rank" do | |
post :create, {:rank => invalid_attributes}, valid_session | |
expect(assigns(:rank)).to be_a_new(Rank) | |
end | |
it "re-renders the 'new' template" do | |
post :create, {:rank => invalid_attributes}, valid_session | |
expect(response).to render_template("new") | |
end | |
end | |
end | |
describe "PUT #update" do | |
context "with valid params" do | |
let(:new_attributes) { | |
{ | |
:name => "aSho Kyu", | |
:belt => "Brown Belt II", | |
:traditional => 'Brown Belt III' | |
} | |
# skip("Add a hash of attributes valid for your model") | |
} | |
it "updates the requested rank" do | |
rank = Rank.create! valid_attributes | |
put :update, {:id => rank.to_param, :rank => new_attributes}, valid_session | |
rank.reload | |
expect(rank.name).to eq('aSho Kyu') | |
expect(rank.belt).to eq('Brown Belt II') | |
expect(rank.traditional).to eq('Brown Belt III') | |
expect(rank.full_rank).to eq('aSho Kyu - Brown Belt II') | |
expect(rank.traditional_rank).to eq('aSho Kyu - Brown Belt III') | |
# skip("Add assertions for updated state") | |
end | |
it "assigns the requested rank as @rank" do | |
rank = Rank.create! valid_attributes | |
put :update, {:id => rank.to_param, :rank => valid_attributes}, valid_session | |
expect(assigns(:rank)).to eq(rank) | |
end | |
it "redirects to the rank" do | |
rank = Rank.create! valid_attributes | |
put :update, {:id => rank.to_param, :rank => valid_attributes}, valid_session | |
expect(response).to redirect_to(rank) | |
end | |
end | |
context "with invalid params" do | |
it "assigns the rank as @rank" do | |
rank = Rank.create! valid_attributes | |
put :update, {:id => rank.to_param, :rank => invalid_attributes}, valid_session | |
expect(assigns(:rank)).to eq(rank) | |
end | |
it "re-renders the 'edit' template" do | |
rank = Rank.create! valid_attributes | |
put :update, {:id => rank.to_param, :rank => invalid_attributes}, valid_session | |
expect(response).to render_template("edit") | |
end | |
end | |
end | |
describe "DELETE #destroy" do | |
it "destroys the requested rank" do | |
rank = Rank.create! valid_attributes | |
expect { | |
delete :destroy, {:id => rank.to_param}, valid_session | |
}.to change(Rank, :count).by(-1) | |
end | |
it "redirects to the ranks list" do | |
rank = Rank.create! valid_attributes | |
delete :destroy, {:id => rank.to_param}, valid_session | |
expect(response).to redirect_to(ranks_url) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/sessions_controller.rb | |
class SessionsController < ApplicationController | |
def new | |
end | |
def create | |
user = User.find_by_email(params[:email]) | |
if user && user.authenticate(params[:password]) | |
# session[:user_id] = user.id | |
if params[:remember_me] | |
cookies.permanent[:auth_token] = user.auth_token | |
else | |
cookies[:auth_token] = user.auth_token | |
end | |
redirect_to root_url, notice: "Logged in!" | |
else | |
flash.now.alert = "Email or password is invalid" | |
render "new" | |
end | |
end | |
def destroy | |
# session[:user_id] = nil | |
cookies.delete(:auth_token) | |
redirect_to root_url, notice: "Logged out!" | |
end | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions/student_permission.rb | |
module Permissions | |
class StudentPermission < BasePermission | |
def initialize(user) | |
allow_action :users, [:new, :create] | |
allow_action :sessions, [:new, :create, :destroy] | |
allow_action :password_resets, [:new, :create, :edit, :update] | |
allow_action :pages, [:show] | |
allow_action :ranks, [:index, :show] | |
allow_action :precepts, [:index, :show] | |
allow_action :bulletins, [:index, :show] | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/users_controller.rb | |
class UsersController < ApplicationController | |
def new | |
@user = User.new | |
end | |
def create | |
@user = User.new(user_params) | |
if @user.save | |
# session[:user_id] = @user.id | |
cookies[:auth_token] = @user.auth_token | |
redirect_to root_url, notice: "Thank you for signing up!" | |
else | |
render "new" | |
end | |
end | |
def edit | |
@user = current_user | |
end | |
def update | |
@user = current_user | |
if @user.update_attributes(user_params) | |
redirect_to root_url, notice: "Updated profile." | |
else | |
render "new" | |
end | |
end | |
private | |
def user_params | |
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :roles_mask, :roles) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissions/visitor_permission.rb | |
module Permissions | |
class VisitorPermission < BasePermission | |
def initialize | |
allow_action :users, [:new, :create] | |
allow_action :sessions, [:new, :create, :destroy] | |
allow_action :password_resets, [:new, :create, :edit, :update] | |
allow_action :pages, [:show] | |
allow_action :ranks, [:index, :show] | |
allow_action :precepts, [:index, :show] | |
allow_action :bulletins, [:index, :show] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment