From 4d4f5deed45c1b92205f9a17eddd07af6acc3eeb Mon Sep 17 00:00:00 2001 From: "konstantin.grabar" Date: Wed, 16 Nov 2011 22:45:01 +0400 Subject: [PATCH] [refs #2249] Remove bitmask. Add new rules. Add some authorize filters. Add some template can? helpers --- Gemfile | 2 +- app/controllers/application_controller.rb | 2 +- .../personal_repositories_controller.rb | 2 ++ app/controllers/platforms_controller.rb | 5 ++++ app/controllers/projects_controller.rb | 2 +- app/models/ability.rb | 29 ++++++++++++++++--- app/models/relation.rb | 16 ++++++++-- app/models/user.rb | 5 +++- app/views/platforms/_list.html.haml | 4 ++- app/views/platforms/forbidden.html.haml | 0 app/views/platforms/show.html.haml | 9 ++++-- app/views/projects/_list.html.haml | 4 +-- app/views/projects/show.html.haml | 4 +-- config/routes.rb | 1 + .../20111116140040_add_roles_to_relations.rb | 11 +++++++ db/schema.rb | 15 +++++----- 16 files changed, 86 insertions(+), 25 deletions(-) create mode 100644 app/views/platforms/forbidden.html.haml create mode 100644 db/migrate/20111116140040_add_roles_to_relations.rb diff --git a/Gemfile b/Gemfile index 04af7b105..5398ab7b4 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ gem 'devise', '~> 1.4.8' gem 'omniauth', '~> 0.3.2' gem 'oa-openid', '~> 0.3.2', :require => 'omniauth/openid' gem 'cancan', '~> 1.6.7' -gem 'bitmask_attributes' +#gem 'bitmask_attributes' gem "haml-rails", '~> 0.3.4' gem "compass", '~> 0.11.5' diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e3b9d64e7..483d06b1f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -10,7 +10,7 @@ class ApplicationController < ActionController::Base helper_method :get_owner rescue_from CanCan::AccessDenied do |exception| - redirect_to root_url, :alert => exception.message + redirect_to forbidden_url, :alert => exception.message end protected diff --git a/app/controllers/personal_repositories_controller.rb b/app/controllers/personal_repositories_controller.rb index c6cad8898..d847be165 100644 --- a/app/controllers/personal_repositories_controller.rb +++ b/app/controllers/personal_repositories_controller.rb @@ -3,6 +3,8 @@ class PersonalRepositoriesController < ApplicationController before_filter :find_repository#, :only => [:show, :destroy, :add_project, :remove_project, :make_private, :settings] before_filter :check_repository #before_filter :check_global_access + + authorize_resource def show #can_perform? @repository if @repository diff --git a/app/controllers/platforms_controller.rb b/app/controllers/platforms_controller.rb index 7f8c2567c..e3389bfcc 100644 --- a/app/controllers/platforms_controller.rb +++ b/app/controllers/platforms_controller.rb @@ -4,6 +4,8 @@ class PlatformsController < ApplicationController before_filter :find_platform, :only => [:freeze, :unfreeze, :clone, :edit, :destroy] before_filter :get_paths, :only => [:new, :create, :clone] #before_filter :check_global_access, :only => [:index, :new, :create]#:except => :easy_urpmi + + authorize_resource def index #@platforms = Platform.visible_to(current_user).paginate(:page => params[:platform_page]) @@ -107,6 +109,9 @@ class PlatformsController < ApplicationController flash[:notice] = t("flash.platform.destroyed") redirect_to root_path end + + def forbidden + end protected def get_paths diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 87ad9d0d1..e0677d87f 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -4,7 +4,7 @@ class ProjectsController < ApplicationController before_filter :get_paths, :only => [:new, :create, :edit, :update] #before_filter :check_global_access, :only => [:index, :new, :create]#:except => :auto_build #check_authorization - #authorize_resource + authorize_resource def index if params[:query] diff --git a/app/models/ability.rb b/app/models/ability.rb index 3d7941bc8..bfe69209b 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -5,14 +5,16 @@ class Ability # Define abilities for the passed in user here. For example: # user ||= User.new # guest user (not logged in) + if user.admin? can :manage, :all else - # Block access to all objects on the site - cannot :read, :all - # Shared rights between guests and registered users can :read, Platform + can :index, [Platform, Project, User, Category, Download] + can :forbidden, Platform + cannot :read, Platform, :visibility => 'hidden' + cannot :read, Platform, :platform_type => 'personal' # Guest rights if user.guest? @@ -24,8 +26,27 @@ class Ability can [:read, :update, :process_build, :build], Project, :owner_type => 'User', :owner_id => user.id # If rules goes one by one CanCan joins them by 'OR' sql operator can :read, Project, :visibility => 'open' - can [:read, :update, :process_build, :build], Project, :collaborators => {:id => user.id} + #can [:read, :update, :process_build, :build], Project, :collaborators => {:id => user.id} + can :read, Project, :relations => {:role => 'read'} + can [:update, :process_build, :build], Project, :relations => {:role => 'write'} + + can :manage, Platform, :owner_type => 'User', :owner_id => user.id + can :read, Platform, :members => {:id => user.id} + + #can :read, Repository + # TODO: Add personal repos rules + + # Same rights for groups: + can [:read, :update, :process_build, :build], Project, :owner_type => 'Group', :owner_id => user.group_ids + can :read, Project, :relations => {:role => 'read', :object_type => 'Group', :object_id => user.group_ids} + can [:update, :process_build, :build], Project, :relations => {:role => 'write', :object_type => 'Group', :object_id => user.group_ids} + + can :manage, Platform, :owner_type => 'Group', :owner_id => user.group_ids + can :read, Platform, :groups => {:id => user.group_ids} end end + + # Shared rights for all users (guests, registered, admin) + cannot :destroy, Platform, :platform_type => 'personal' end end \ No newline at end of file diff --git a/app/models/relation.rb b/app/models/relation.rb index 3bf68fcd0..3248ddd1b 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -2,10 +2,14 @@ class Relation < ActiveRecord::Base belongs_to :target, :polymorphic => true belongs_to :object, :polymorphic => true - has_many :role_lines - has_many :roles, :autosave => true, :through => :role_lines + #has_many :role_lines + #has_many :roles, :autosave => true, :through => :role_lines - bitmask :roles, :as => [:read, :update] + ROLES = %w[read write] + + validates :role, :inclusion => {:in => ROLES} + + #bitmask :roles, :as => [:read, :update] after_create { with_ga do |ga| @@ -23,6 +27,12 @@ class Relation < ActiveRecord::Base end end if target_type == 'Project' and object_type == 'User' } + + #after_create { + # if self.role.blank? + # update_attribute(:role, 'read') + # end + #} scope :by_object, lambda {|obj| {:conditions => ['object_id = ? AND object_type = ?', obj.id, obj.class.to_s]}} scope :by_target, lambda {|tar| {:conditions => ['target_id = ? AND target_type = ?', tar.id, tar.class.to_s]}} diff --git a/app/models/user.rb b/app/models/user.rb index 74e8d4bab..50408bd71 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,6 +1,8 @@ class User < ActiveRecord::Base relationable :as => :object inherit_rights_from :groups + + ROLES = %w[admin] devise :database_authenticatable, :registerable, :omniauthable, # :token_authenticatable, :encryptable, :timeoutable :recoverable, :rememberable, :validatable #, :trackable, :confirmable, :lockable @@ -31,6 +33,7 @@ class User < ActiveRecord::Base validate lambda { errors.add(:uname, I18n.t('flash.user.group_uname_exists')) if Group.exists? :uname => uname } + validates :role, :inclusion => {:in => ROLES} attr_accessible :email, :password, :password_confirmation, :remember_me, :login, :name, :ssh_key, :uname attr_readonly :uname @@ -51,7 +54,7 @@ class User < ActiveRecord::Base # after_create() { UserMailer.new_user_notification(self).deliver } def admin? - self.id == 1 + role == 'admin' end def guest? diff --git a/app/views/platforms/_list.html.haml b/app/views/platforms/_list.html.haml index c66e74b41..233487bad 100644 --- a/app/views/platforms/_list.html.haml +++ b/app/views/platforms/_list.html.haml @@ -10,4 +10,6 @@ %td = platform.distrib_type %td.last - #{link_to t("layout.show"), platform_path(platform)} | #{link_to t("layout.delete"), platform_path(platform), :method => :delete, :confirm => t("layout.platforms.confirm_delete")} + = link_to t("layout.show"), platform_path(platform) + | + = link_to t("layout.delete"), platform_path(platform), :method => :delete, :confirm => t("layout.platforms.confirm_delete") if can? :destroy, platform diff --git a/app/views/platforms/forbidden.html.haml b/app/views/platforms/forbidden.html.haml new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/platforms/show.html.haml b/app/views/platforms/show.html.haml index 924374a9f..cb6672059 100644 --- a/app/views/platforms/show.html.haml +++ b/app/views/platforms/show.html.haml @@ -83,7 +83,9 @@ %td = link_to repository.name, platform_repository_path(@platform, repository) %td.last - #{link_to t("layout.show"), platform_repository_path(@platform, repository)} | #{link_to t("layout.delete"), platform_repository_path(@platform, repository), :method => :delete, :confirm => t("layout.repositories.confirm_delete")} + = link_to t("layout.show"), platform_repository_path(@platform, repository)} + | + = link_to t("layout.delete"), platform_repository_path(@platform, repository), :method => :delete, :confirm => t("layout.repositories.confirm_delete") if can? :destroy, project .actions-bar.wat-cf .actions @@ -106,7 +108,10 @@ %td = link_to product.name, [@platform, product] %td.last - #{link_to t("layout.edit"), edit_platform_product_path(@platform, product)} | #{link_to t("layout.delete"), platform_product_path(@platform, product), :method => :delete, :confirm => t("layout.products.confirm_delete")} #{(product.can_clone? ? "| #{link_to t("layout.products.clone"), clone_platform_product_path(@platform, product)}" : "").html_safe } + = link_to t("layout.edit"), edit_platform_product_path(@platform, product)} + | + = link_to t("layout.delete"), platform_product_path(@platform, product), :method => :delete, :confirm => t("layout.products.confirm_delete") if can? :destroy, project + = (product.can_clone? ? "| #{link_to t("layout.products.clone"), clone_platform_product_path(@platform, product)}" : "").html_safe .actions-bar.wat-cf .actions - content_for :sidebar, render(:partial => 'sidebar') diff --git a/app/views/projects/_list.html.haml b/app/views/projects/_list.html.haml index 36e7f964d..72ad96be9 100644 --- a/app/views/projects/_list.html.haml +++ b/app/views/projects/_list.html.haml @@ -8,6 +8,6 @@ %td= link_to "#{project.name} (#{project.unixname})", project %td= link_to "#{project.owner.name} (#{project.owner.uname})", project.owner %td - = link_to t("layout.edit"), edit_project_path(project) + = link_to t("layout.edit"), edit_project_path(project) if can? :update, project | - = link_to t("layout.delete"), project_path(project), :method => :delete, :confirm => t("layout.projects.confirm_delete") + = link_to t("layout.delete"), project_path(project), :method => :delete, :confirm => t("layout.projects.confirm_delete") if can? :destroy, project diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index 64578a91d..4486a1b7e 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -36,8 +36,8 @@ = git_repo_url @project.git_repo_name .wat-cf - = link_to image_tag("web-app-theme/icons/application_edit.png", :alt => t("layout.edit")) + " " + t("layout.edit"), edit_project_path(@project), :class => "button" - = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_path(@project), :method => "delete", :class => "button", :confirm => t("layout.projects.confirm_delete") + = link_to image_tag("web-app-theme/icons/application_edit.png", :alt => t("layout.edit")) + " " + t("layout.edit"), edit_project_path(@project), :class => "button" if can? :update, @project + = link_to image_tag("web-app-theme/icons/cross.png", :alt => t("layout.delete")) + " " + t("layout.delete"), project_path(@project), :method => "delete", :class => "button", :confirm => t("layout.projects.confirm_delete") if can? :destroy, project %a{ :name => "build_lists"} .block diff --git a/config/routes.rb b/config/routes.rb index 79afcfe95..3df6a63a5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -148,4 +148,5 @@ Rosa::Application.routes.draw do match '/projects/:project_id/git/commit/raw/:commit_hash/*path', :controller => "git/blobs", :action => :raw, :as => :raw_commit root :to => "platforms#index" + match '/forbidden', :to => 'platforms#forbidden', :as => 'forbidden' end diff --git a/db/migrate/20111116140040_add_roles_to_relations.rb b/db/migrate/20111116140040_add_roles_to_relations.rb new file mode 100644 index 000000000..5d2b70884 --- /dev/null +++ b/db/migrate/20111116140040_add_roles_to_relations.rb @@ -0,0 +1,11 @@ +class AddRolesToRelations < ActiveRecord::Migration + def self.up + add_column :relations, :role, :string + add_column :users, :role, :string + end + + def self.down + remove_column :relations, :role + remove_column :users, :role + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index fba91a0d8..2ce45740f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20111111184657) do +ActiveRecord::Schema.define(:version => 20111116140040) do create_table "arches", :force => true do |t| t.string "name", :null => false @@ -228,9 +228,9 @@ ActiveRecord::Schema.define(:version => 20111111184657) do t.string "object_type" t.integer "target_id" t.string "target_type" - t.integer "role_id" t.datetime "created_at" t.datetime "updated_at" + t.string "role" end create_table "repositories", :force => true do |t| @@ -282,17 +282,18 @@ ActiveRecord::Schema.define(:version => 20111111184657) do create_table "users", :force => true do |t| t.string "name" - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "password_salt", :default => "", :null => false t.string "reset_password_token" - t.datetime "reset_password_sent_at" + t.string "remember_token" t.datetime "remember_created_at" t.datetime "created_at" t.datetime "updated_at" - t.string "uname" t.text "ssh_key" - t.integer "role_id" + t.string "uname" t.integer "global_role_id" + t.string "role" end add_index "users", ["email"], :name => "index_users_on_email", :unique => true