#465: added pundit gem, wip...
This commit is contained in:
parent
f5a68ed4ae
commit
4fec2213c8
3
Gemfile
3
Gemfile
|
@ -14,8 +14,7 @@ gem 'omniauth-facebook'
|
|||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-github'
|
||||
# gem 'omniauth-openid', '~> 1.0.1'
|
||||
# gem 'cancan', '1.6.10'
|
||||
gem 'cancan', git: 'git://github.com/rosa-abf/cancan.git', tag: '1.6.10-abf'
|
||||
gem 'pundit'
|
||||
|
||||
gem 'ancestry'
|
||||
gem 'paperclip'
|
||||
|
|
11
Gemfile.lock
11
Gemfile.lock
|
@ -26,13 +26,6 @@ GIT
|
|||
ransack (~> 1.3)
|
||||
sass-rails
|
||||
|
||||
GIT
|
||||
remote: git://github.com/rosa-abf/cancan.git
|
||||
revision: fe1089b70c08d3ed11bac4f8e69ecb3d1d9adc29
|
||||
tag: 1.6.10-abf
|
||||
specs:
|
||||
cancan (1.6.10)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/rosa-abf/grack.git
|
||||
revision: 020be3fef3fb308b9d214252522aa5945bf6584a
|
||||
|
@ -349,6 +342,8 @@ GEM
|
|||
activemodel (>= 4.0.1, < 5.0)
|
||||
puma (2.11.1)
|
||||
rack (>= 1.1, < 2.0)
|
||||
pundit (0.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
pygments.rb (0.6.2)
|
||||
posix-spawn (~> 0.3.6)
|
||||
yajl-ruby (~> 1.2.0)
|
||||
|
@ -590,7 +585,6 @@ DEPENDENCIES
|
|||
better_errors
|
||||
binding_of_caller
|
||||
bootstrap-sass
|
||||
cancan!
|
||||
cape
|
||||
capistrano
|
||||
capistrano_colors
|
||||
|
@ -637,6 +631,7 @@ DEPENDENCIES
|
|||
pg
|
||||
protected_attributes
|
||||
puma
|
||||
pundit
|
||||
rack-throttle (~> 0.3.0)
|
||||
rack-utf8_sanitizer
|
||||
rails (= 4.1.9)
|
||||
|
|
|
@ -4,7 +4,7 @@ class Api::V1::BaseController < ApplicationController
|
|||
|
||||
helper_method :member_path
|
||||
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
rescue_from Pundit::NotAuthorizedError do |exception|
|
||||
respond_to do |format|
|
||||
format.json { render json: {message: t('flash.exception_message')}.to_json, status: 403 }
|
||||
format.csv { render text: t('flash.exception_message'), status: 403 }
|
||||
|
|
|
@ -12,7 +12,7 @@ class Api::V1::ProjectsController < Api::V1::BaseController
|
|||
end
|
||||
|
||||
def get_id
|
||||
if @project = Project.find_by_owner_and_name(params[:owner], params[:name])
|
||||
if @project = Project.find_by_owner_and_name_cached(params[:owner], params[:name])
|
||||
authorize! :show, @project
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound
|
||||
|
|
|
@ -40,7 +40,7 @@ class Api::V1::RepositoriesController < Api::V1::BaseController
|
|||
key, now = [@repository.platform.id, :repository_packages], Time.zone.now
|
||||
last_request = Rails.cache.read(key)
|
||||
if last_request.present? && last_request + 15.minutes > now
|
||||
raise CanCan::AccessDenied
|
||||
raise Pundit::NotAuthorizedError
|
||||
else
|
||||
|
||||
Rails.cache.write(key, now, expires_at: 15.minutes)
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
include StrongParams
|
||||
include Pundit
|
||||
|
||||
AIRBRAKE_IGNORE = [
|
||||
ActionController::InvalidAuthenticityToken,
|
||||
AbstractController::ActionNotFound
|
||||
|
@ -14,6 +17,7 @@ class ApplicationController < ActionController::Base
|
|||
before_action :set_locale
|
||||
before_action -> { EventLog.current_controller = self },
|
||||
only: [:create, :destroy, :open_id, :cancel, :publish, :change_visibility] # :update
|
||||
before_action :banned?
|
||||
after_action -> { EventLog.current_controller = nil }
|
||||
|
||||
helper_method :get_owner
|
||||
|
@ -27,7 +31,7 @@ class ApplicationController < ActionController::Base
|
|||
AbstractController::ActionNotFound, with: :render_404
|
||||
end
|
||||
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
rescue_from Pundit::NotAuthorizedError do |exception|
|
||||
redirect_to forbidden_url, alert: t("flash.exception_message")
|
||||
end
|
||||
|
||||
|
@ -40,6 +44,16 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
protected
|
||||
|
||||
# Disables access to site for banned users
|
||||
def banned?
|
||||
authorize :user, :banned?
|
||||
# if user_signed_in? && current_user.is_banned?
|
||||
# sign_out current_user
|
||||
# flash[:error] = I18n.t('messages.account_suspended')
|
||||
# redirect_to root_path
|
||||
# end
|
||||
end
|
||||
|
||||
# For this example, we are simply using token authentication
|
||||
# via parameters. However, anyone could use Rails's token
|
||||
# authentication features to get the token from a header.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
module StrongParams
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
protected
|
||||
|
||||
def permit_params(param_name, *accessible)
|
||||
(params[param_name] || ActionController::Parameters.new).permit(*accessible.flatten)
|
||||
end
|
||||
end
|
|
@ -6,7 +6,7 @@ class Groups::MembersController < Groups::BaseController
|
|||
end
|
||||
|
||||
def update
|
||||
raise CanCan::AccessDenied if @group.owner_id.to_s == params[:member_id]
|
||||
raise Pundit::NotAuthorizedError if @group.owner_id.to_s == params[:member_id]
|
||||
|
||||
relation = @group.actors.where(actor_id: params[:member_id], actor_type: 'User').first
|
||||
relation ||= @group.actors.build(actor_id: params[:member_id], actor_type: 'User')
|
||||
|
|
|
@ -3,14 +3,14 @@ class Platforms::PlatformsController < Platforms::BaseController
|
|||
|
||||
before_action :authenticate_user!
|
||||
skip_before_action :authenticate_user!, only: [:advisories, :members, :show] if APP_CONFIG['anonymous_access']
|
||||
load_and_authorize_resource
|
||||
# load_and_authorize_resource
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {}
|
||||
|
||||
format.json {
|
||||
@platforms = @platforms.accessible_by(current_ability, :related)
|
||||
@platforms = PlatformPolicy::Scope.new(current_user, Platform).related
|
||||
@platforms_count = @platforms.count
|
||||
@platforms = @platforms.paginate(page: current_page, per_page: Platform.per_page)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ class Platforms::PlatformsController < Platforms::BaseController
|
|||
end
|
||||
|
||||
def show
|
||||
authorize @platform = Platform.find_cached(params[:id])
|
||||
end
|
||||
|
||||
def new
|
||||
|
|
|
@ -125,7 +125,7 @@ class Projects::BuildListsController < Projects::BaseController
|
|||
end
|
||||
|
||||
def dependent_projects
|
||||
raise CanCan::AccessDenied if @build_list.save_to_platform.personal?
|
||||
raise Pundit::NotAuthorizedError if @build_list.save_to_platform.personal?
|
||||
|
||||
if request.post?
|
||||
prs = params[:build_list]
|
||||
|
|
|
@ -5,7 +5,7 @@ class Projects::Git::BaseController < Projects::BaseController
|
|||
before_action :authenticate_user, only: %i(show index blame raw archive diff tags branches)
|
||||
end
|
||||
|
||||
load_and_authorize_resource :project
|
||||
# load_and_authorize_resource :project
|
||||
before_action :set_treeish_and_path
|
||||
before_action :set_branch_and_tree
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ class Projects::PullRequestsController < Projects::BaseController
|
|||
end
|
||||
|
||||
def find_destination_project bang=true
|
||||
project = Project.find_by_owner_and_name params[:to_project]
|
||||
project = Project.find_by_owner_and_name_cached params[:to_project]
|
||||
raise ActiveRecord::RecordNotFound if bang && !project
|
||||
project || @project.pull_requests.last.try(:to_project) || @project.root
|
||||
end
|
||||
|
|
|
@ -57,7 +57,7 @@ class BuildScript < ActiveRecord::Base
|
|||
|
||||
def attach_project
|
||||
if @project_name.present?
|
||||
self.project = Project.find_by_owner_and_name(@project_name)
|
||||
self.project = Project.find_by_owner_and_name_cached(@project_name)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Private: Finders of all sorts: methods to find FlashNotify records, methods to find
|
||||
# other records which belong to given FlashNotify.
|
||||
#
|
||||
# This module gets included into FlashNotify.
|
||||
module FlashNotify::Finders
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :published, -> { where(published: true) }
|
||||
|
||||
after_commit :clear_caches
|
||||
after_touch :clear_caches
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
# Public: Get cached first published FlashNotify record.
|
||||
#
|
||||
# Returns FlashNotify record or nil.
|
||||
def published_first_cached
|
||||
Rails.cache.fetch('FlashNotify.published.first') do
|
||||
published.first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Private: after_commit and after_touch hook which clears find_cached cache.
|
||||
def clear_caches
|
||||
Rails.cache.delete('FlashNotify.published.first')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
# Private: Finders of all sorts: methods to find Platform records, methods to find
|
||||
# other records which belong to given Platform.
|
||||
#
|
||||
# This module gets included into Platform.
|
||||
module Platform::Finders
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
|
||||
scope :search_order, -> { order(:name) }
|
||||
scope :search, -> (q) { where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%") }
|
||||
scope :by_visibilities, -> (v) { where(visibility: v) }
|
||||
scope :opened, -> { where(visibility: Platform::VISIBILITY_OPEN) }
|
||||
scope :hidden, -> { where(visibility: Platform::VISIBILITY_HIDDEN) }
|
||||
scope :by_type, -> (type) { where(platform_type: type) if type.present? }
|
||||
scope :main, -> { by_type(Platform::TYPE_MAIN) }
|
||||
scope :personal, -> { by_type(Platform::TYPE_PERSONAL) }
|
||||
scope :waiting_for_regeneration, -> { where(status: Platform::WAITING_FOR_REGENERATION) }
|
||||
|
||||
after_commit :clear_caches
|
||||
after_touch :clear_caches
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
# Public: Get cached Platform record by ID or slug.
|
||||
#
|
||||
# platform_id - ID or Slug (Numeric/String)
|
||||
#
|
||||
# Returns Platform record.
|
||||
# Raises ActiveRecord::RecordNotFound if nothing was found.
|
||||
def find_cached(platform_id)
|
||||
Rails.cache.fetch(['Platform.find', platform_id]) do
|
||||
find(platform_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Private: after_commit and after_touch hook which clears find_cached cache.
|
||||
def clear_caches
|
||||
Rails.cache.delete(['Platform.find', id])
|
||||
Rails.cache.delete(['Platform.find', slug])
|
||||
|
||||
if chg = previous_changes["slug"]
|
||||
Rails.cache.delete(['Platform.find', chg.first])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,82 @@
|
|||
# Private: Finders of all sorts: methods to find Project records, methods to find
|
||||
# other records which belong to given Project.
|
||||
#
|
||||
# This module gets included into Project.
|
||||
module Project::Finders
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
|
||||
scope :recent, -> { order(:name) }
|
||||
scope :search_order, -> { order('CHAR_LENGTH(projects.name) ASC') }
|
||||
scope :search, ->(q) {
|
||||
q = q.to_s.strip
|
||||
by_name("%#{q}%").search_order if q.present?
|
||||
}
|
||||
scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? }
|
||||
scope :by_owner, ->(name) { where('projects.owner_uname ILIKE ?', "%#{name}%") if name.present? }
|
||||
scope :by_owner_and_name, ->(*params) {
|
||||
term = params.map(&:strip).join('/').downcase
|
||||
where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present?
|
||||
}
|
||||
scope :by_visibilities, ->(v) { where(visibility: v) }
|
||||
scope :opened, -> { where(visibility: 'open') }
|
||||
scope :package, -> { where(is_package: true) }
|
||||
scope :addable_to_repository, ->(repository_id) {
|
||||
where('projects.id NOT IN (
|
||||
SELECT ptr.project_id
|
||||
FROM project_to_repositories AS ptr
|
||||
WHERE ptr.repository_id = ?)', repository_id)
|
||||
}
|
||||
scope :by_owners, ->(group_owner_ids, user_owner_ids) {
|
||||
where("(projects.owner_id in (?) AND projects.owner_type = 'Group') OR
|
||||
(projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids)
|
||||
}
|
||||
|
||||
scope :project_aliases, ->(project) {
|
||||
where.not(id: project.id).
|
||||
where('alias_from_id IN (:ids) OR id IN (:ids)', { ids: [project.alias_from_id, project.id].compact })
|
||||
}
|
||||
|
||||
after_commit :clear_caches
|
||||
after_touch :clear_caches
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
# Public: Get cached Project record by ID or slug.
|
||||
#
|
||||
# Returns Project record.
|
||||
# Raises ActiveRecord::RecordNotFound if nothing was found.
|
||||
def find_by_owner_and_name_cached(first, last = nil)
|
||||
Rails.cache.fetch(['Project.find_by_owner_and_name', first, last]) do
|
||||
find_by_owner_and_name(first, last)
|
||||
end
|
||||
end
|
||||
|
||||
def find_by_owner_and_name(first, last = nil)
|
||||
arr = first.try(:split, '/') || []
|
||||
arr = (arr << last).compact
|
||||
return nil if arr.length != 2
|
||||
where(owner_uname: arr.first, name: arr.last).first || by_owner_and_name(*arr).first
|
||||
end
|
||||
|
||||
def find_by_owner_and_name!(first, last = nil)
|
||||
find_by_owner_and_name_cached(first, last) or raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Private: after_commit and after_touch hook which clears find_cached cache.
|
||||
def clear_caches
|
||||
Rails.cache.delete(['Project.find_by_owner_and_name', owner_uname, name])
|
||||
Rails.cache.delete(['Project.find_by_owner_and_name', name_with_owner])
|
||||
Rails.cache.delete(['Project.find', id])
|
||||
Rails.cache.delete(['Project.find', slug])
|
||||
|
||||
if chg = previous_changes["slug"]
|
||||
Rails.cache.delete(['Project.find', chg.first])
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,15 +1,13 @@
|
|||
require 'digest/md5'
|
||||
|
||||
class FlashNotify < ActiveRecord::Base
|
||||
# attr_accessible :title, :body
|
||||
include FlashNotify::Finders
|
||||
|
||||
STATUSES = %w[error success info]
|
||||
|
||||
validates :status, inclusion: {in: STATUSES}
|
||||
validates :body_ru, :body_en, :status, presence: true
|
||||
|
||||
scope :published, -> { where(published: true) }
|
||||
|
||||
attr_accessible :body_ru, :body_en, :status, :published
|
||||
|
||||
def hash_id
|
||||
|
|
|
@ -109,7 +109,7 @@ class Issue < ActiveRecord::Base
|
|||
owner_uname = Regexp.last_match[1].presence || Regexp.last_match[2].presence || project.owner.uname
|
||||
project_name = Regexp.last_match[1] ? Regexp.last_match[2] : project.name
|
||||
serial_id = Regexp.last_match[3]
|
||||
project = Project.find_by_owner_and_name(owner_uname.chomp('/'), project_name)
|
||||
project = Project.find_by_owner_and_name_cached(owner_uname.chomp('/'), project_name)
|
||||
return nil unless project
|
||||
return nil unless current_ability.can? :show, project
|
||||
project.issues.where(serial_id: serial_id).first
|
||||
|
|
|
@ -8,6 +8,7 @@ class Platform < ActiveRecord::Base
|
|||
include EventLoggable
|
||||
include EmptyMetadata
|
||||
include DefaultBranchable
|
||||
include Platform::Finders
|
||||
|
||||
self.per_page = 20
|
||||
|
||||
|
@ -96,16 +97,6 @@ class Platform < ActiveRecord::Base
|
|||
after_create -> { symlink_directory unless hidden? }
|
||||
after_destroy -> { remove_symlink_directory unless hidden? }
|
||||
|
||||
scope :search_order, -> { order(:name) }
|
||||
scope :search, -> (q) { where("#{table_name}.name ILIKE ?", "%#{q.to_s.strip}%") }
|
||||
scope :by_visibilities, -> (v) { where(visibility: v) }
|
||||
scope :opened, -> { where(visibility: VISIBILITY_OPEN) }
|
||||
scope :hidden, -> { where(visibility: VISIBILITY_HIDDEN) }
|
||||
scope :by_type, -> (type) { where(platform_type: type) if type.present? }
|
||||
scope :main, -> { by_type(TYPE_MAIN) }
|
||||
scope :personal, -> { by_type(TYPE_PERSONAL) }
|
||||
scope :waiting_for_regeneration, -> { where(status: WAITING_FOR_REGENERATION) }
|
||||
|
||||
accepts_nested_attributes_for :platform_arch_settings, allow_destroy: true
|
||||
attr_accessible :name,
|
||||
:distrib_type,
|
||||
|
|
|
@ -8,6 +8,7 @@ class Project < ActiveRecord::Base
|
|||
include UrlHelper
|
||||
include EventLoggable
|
||||
include Project::DefaultBranch
|
||||
include Project::Finders
|
||||
|
||||
VISIBILITIES = ['open', 'hidden']
|
||||
MAX_OWN_PROJECTS = 32000
|
||||
|
@ -67,37 +68,6 @@ class Project < ActiveRecord::Base
|
|||
:autostart_status
|
||||
attr_readonly :owner_id, :owner_type
|
||||
|
||||
scope :recent, -> { order(:name) }
|
||||
scope :search_order, -> { order('CHAR_LENGTH(projects.name) ASC') }
|
||||
scope :search, ->(q) {
|
||||
q = q.to_s.strip
|
||||
by_name("%#{q}%").search_order if q.present?
|
||||
}
|
||||
scope :by_name, ->(name) { where('projects.name ILIKE ?', name) if name.present? }
|
||||
scope :by_owner, ->(name) { where('projects.owner_uname ILIKE ?', "%#{name}%") if name.present? }
|
||||
scope :by_owner_and_name, ->(*params) {
|
||||
term = params.map(&:strip).join('/').downcase
|
||||
where("lower(concat(owner_uname, '/', name)) ILIKE ?", "%#{term}%") if term.present?
|
||||
}
|
||||
scope :by_visibilities, ->(v) { where(visibility: v) }
|
||||
scope :opened, -> { where(visibility: 'open') }
|
||||
scope :package, -> { where(is_package: true) }
|
||||
scope :addable_to_repository, ->(repository_id) {
|
||||
where('projects.id NOT IN (
|
||||
SELECT ptr.project_id
|
||||
FROM project_to_repositories AS ptr
|
||||
WHERE ptr.repository_id = ?)', repository_id)
|
||||
}
|
||||
scope :by_owners, ->(group_owner_ids, user_owner_ids) {
|
||||
where("(projects.owner_id in (?) AND projects.owner_type = 'Group') OR
|
||||
(projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids)
|
||||
}
|
||||
|
||||
scope :project_aliases, ->(project) {
|
||||
where.not(id: project.id).
|
||||
where('alias_from_id IN (:ids) OR id IN (:ids)', { ids: [project.alias_from_id, project.id].compact })
|
||||
}
|
||||
|
||||
before_validation :truncate_name, on: :create
|
||||
before_save -> { self.owner_uname = owner.uname if owner_uname.blank? || owner_id_changed? || owner_type_changed? }
|
||||
before_create :set_maintainer
|
||||
|
@ -106,19 +76,6 @@ class Project < ActiveRecord::Base
|
|||
|
||||
attr_accessor :url, :srpms_list, :mass_import, :add_to_repository_id
|
||||
|
||||
class << self
|
||||
def find_by_owner_and_name(first, last = nil)
|
||||
arr = first.try(:split, '/') || []
|
||||
arr = (arr << last).compact
|
||||
return nil if arr.length != 2
|
||||
where(owner_uname: arr.first, name: arr.last).first || by_owner_and_name(*arr).first
|
||||
end
|
||||
|
||||
def find_by_owner_and_name!(first, last = nil)
|
||||
find_by_owner_and_name(first, last) or raise ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
||||
def init_mass_import
|
||||
Project.perform_later :low, :run_mass_import, url, srpms_list, visibility, owner, add_to_repository_id
|
||||
end
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
class AdvisoryPolicy < ApplicationPolicy
|
||||
|
||||
def index?
|
||||
true
|
||||
end
|
||||
|
||||
def show?
|
||||
true
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,117 @@
|
|||
class ApplicationPolicy
|
||||
attr_reader :user, :record
|
||||
|
||||
def initialize(user, record)
|
||||
# raise Pundit::NotAuthorizedError, 'must be logged in' unless user
|
||||
@user = user || User.new
|
||||
@record = record
|
||||
end
|
||||
|
||||
BASIC_ACTIONS = %i(index? show? create? update? destroy? destroy_all?)
|
||||
|
||||
def index?
|
||||
false
|
||||
end
|
||||
|
||||
def show?
|
||||
false
|
||||
end
|
||||
|
||||
def new?
|
||||
create?
|
||||
end
|
||||
|
||||
def edit?
|
||||
update?
|
||||
end
|
||||
|
||||
def update?
|
||||
false
|
||||
end
|
||||
|
||||
def create?
|
||||
false
|
||||
end
|
||||
|
||||
def destroy?
|
||||
false
|
||||
end
|
||||
|
||||
def permitted_attributes
|
||||
[]
|
||||
end
|
||||
|
||||
class Scope
|
||||
attr_reader :user, :scope
|
||||
|
||||
def initialize(user, scope)
|
||||
@user = user
|
||||
@scope = scope
|
||||
end
|
||||
|
||||
def resolve
|
||||
scope
|
||||
end
|
||||
|
||||
# Public: Get user's group ids.
|
||||
#
|
||||
# Returns the Array of group ids.
|
||||
def user_group_ids
|
||||
Rails.cache.fetch(['ApplicationPolicy#user_group_ids', user.id]) do
|
||||
user.group_ids
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Public: Check if provided user is the current user.
|
||||
#
|
||||
# Returns true if it is, false otherwise.
|
||||
def current_user?(u)
|
||||
u == user
|
||||
end
|
||||
|
||||
# Public: Check if provided user is guest.
|
||||
#
|
||||
# Returns true if he is, false otherwise.
|
||||
def is_guest?
|
||||
user.new_record?
|
||||
end
|
||||
|
||||
# Public: Check if provided user is user.
|
||||
#
|
||||
# Returns true if he is, false otherwise.
|
||||
def is_user?
|
||||
user.persisted?
|
||||
end
|
||||
|
||||
# Public: Check if provided user is tester.
|
||||
#
|
||||
# Returns true if he is, false otherwise.
|
||||
def is_tester?
|
||||
user.role == 'tester'
|
||||
end
|
||||
|
||||
# Public: Check if provided user is system.
|
||||
#
|
||||
# Returns true if he is, false otherwise.
|
||||
def is_system?
|
||||
user.role == 'system'
|
||||
end
|
||||
|
||||
# Public: Check if provided user is admin.
|
||||
#
|
||||
# Returns true if he is, false otherwise.
|
||||
def is_admin?
|
||||
user.role == 'admin'
|
||||
end
|
||||
|
||||
# Public: Check if provided user is banned.
|
||||
#
|
||||
# Returns true if he is, false otherwise.
|
||||
def is_banned?
|
||||
user.role == 'banned'
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
class BuildListPolicy < ApplicationPolicy
|
||||
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
class GroupPolicy < ApplicationPolicy
|
||||
|
||||
end
|
|
@ -0,0 +1,62 @@
|
|||
class PlatformPolicy < ApplicationPolicy
|
||||
|
||||
def index?
|
||||
true
|
||||
end
|
||||
|
||||
def show?
|
||||
return true unless record.hidden?
|
||||
return true if record.owner == user
|
||||
return true if owner?
|
||||
end
|
||||
|
||||
def create?
|
||||
is_admin?
|
||||
end
|
||||
|
||||
def members?
|
||||
owner? || local_admin?
|
||||
end
|
||||
|
||||
def clone?
|
||||
return false if record.personal?
|
||||
owner? || local_admin?
|
||||
end
|
||||
|
||||
class Scope < Scope
|
||||
|
||||
def related
|
||||
scope.where <<-SQL, { user_id: user.id, user_group_ids: user_group_ids, platform_ids: related_platform_ids }
|
||||
(
|
||||
platforms.id IN (:platform_ids)
|
||||
) OR (
|
||||
platforms.owner_type = 'User' AND platforms.owner_id = :user_id
|
||||
) OR (
|
||||
platforms.owner_type = 'Group' AND platforms.owner_id IN (:user_group_ids)
|
||||
)
|
||||
SQL
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def related_platform_ids
|
||||
Rails.cache.fetch(['PlatformPolicy::Scope#related_platform_ids', user.id]) do
|
||||
user.repositories.pluck(:platform_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def owner?
|
||||
record.owner == user ||
|
||||
record.owner.is_a?(Group) && user_group_ids.include?(record.owner_id)
|
||||
end
|
||||
|
||||
def local_admin?
|
||||
Rails.cache.fetch(['PlatformPolicy#local_admin?', record, user]) do
|
||||
user.best_role(record) == 'admin'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
class ProductPolicy < ApplicationPolicy
|
||||
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
class ProjectPolicy < ApplicationPolicy
|
||||
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
class StatisticPolicy < ApplicationPolicy
|
||||
|
||||
end
|
|
@ -0,0 +1,6 @@
|
|||
class UserPolicy < ApplicationPolicy
|
||||
|
||||
def banned?
|
||||
!is_banned?
|
||||
end
|
||||
end
|
|
@ -15,7 +15,7 @@ json.feed do
|
|||
end if user
|
||||
|
||||
project_name_with_owner = "#{item.data[:project_owner]}/#{item.data[:project_name]}"
|
||||
@project = Project.find_by_owner_and_name(item.data[:project_owner], item.data[:project_name])
|
||||
@project = Project.find_by_owner_and_name_cached(item.data[:project_owner], item.data[:project_name])
|
||||
|
||||
json.project_name_with_owner project_name_with_owner
|
||||
json.partial! item.partial, item: item, project_name_with_owner: project_name_with_owner
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- if current_user || APP_CONFIG['anonymous_access']
|
||||
.flash_notify
|
||||
- if (flash_notify = FlashNotify.published.first) && flash_notify.should_show?(cookies[:flash_notify_hash])
|
||||
- if (flash_notify = FlashNotify.published_first_cached) && flash_notify.should_show?(cookies[:flash_notify_hash])
|
||||
.alert{class: "alert-#{flash_notify.status}"}
|
||||
= flash_notify.body(I18n.locale).html_safe
|
||||
%a.close#close-alert{:'data-dismiss'=>"alert", href: "#"} ×
|
||||
|
|
|
@ -16,7 +16,7 @@ html
|
|||
== yield :submenu if content_for?(:submenu)
|
||||
|
||||
- if current_user || APP_CONFIG['anonymous_access']
|
||||
- if (flash_notify = FlashNotify.published.first) && flash_notify.should_show?(cookies[:flash_notify_hash])
|
||||
- if (flash_notify = FlashNotify.published_first_cached) && flash_notify.should_show?(cookies[:flash_notify_hash])
|
||||
javascript:
|
||||
var FLASH_HASH_ID = "#{flash_notify.hash_id}";
|
||||
.notify.alert.alert-dismissable.text-center class=alert_class(flash_notify.status)
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
%li
|
||||
= image_tag 'square.png'
|
||||
= link_to t('bottom_menu.developer_api'), t('bottom_menu.developer_api_url')
|
||||
-if pr = Project.find_by_owner_and_name('abf/abf-ideas')
|
||||
-if pr = Project.find_by_owner_and_name_cached('abf/abf-ideas')
|
||||
%li
|
||||
= image_tag 'square.png'
|
||||
= link_to t('bottom_menu.abf_ideas'), project_issues_url(pr)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
%li= link_to t('bottom_menu.support'), contact_url
|
||||
%li ·
|
||||
%li= link_to t('bottom_menu.developer_api'), t('bottom_menu.developer_api_url')
|
||||
-if pr = Project.find_by_owner_and_name('abf/abf-ideas')
|
||||
- if pr = Project.find_by_owner_and_name_cached('abf/abf-ideas')
|
||||
%li ·
|
||||
%li= link_to t('bottom_menu.abf_ideas'), project_issues_url(pr)
|
||||
%li ·
|
||||
|
|
|
@ -12,7 +12,7 @@ nav.navbar.navbar-inverse.top_menu role = "navigation"
|
|||
#top-menu-navbar-collapse.collapse.navbar-collapse
|
||||
ul.nav.navbar-nav
|
||||
- (collection = t 'top_menu').each do |base, title|
|
||||
- if can? :index, base.to_s.classify.constantize
|
||||
- if policy(base).index?
|
||||
li class=top_menu_class(base)
|
||||
a href=send("#{base}_path")
|
||||
i.fa.hidden-sm class=top_menu_icon(base)
|
||||
|
|
|
@ -22,24 +22,24 @@
|
|||
= link_to t("layout.repositories.list_header"), platform_repositories_path(@platform)
|
||||
li class=('active' if contr == :contents)
|
||||
= link_to t('layout.platforms.contents'), platform_contents_path(@platform)
|
||||
- if can? :show, @platform
|
||||
- if policy(@platform).show?
|
||||
li class=('active' if act == :index && contr == :maintainers)
|
||||
= link_to t("layout.platforms.maintainers"), platform_maintainers_path(@platform)
|
||||
li class=('active' if contr == :mass_builds)
|
||||
= link_to t("layout.platforms.mass_build"), platform_mass_builds_path(@platform)
|
||||
- if can? :read, @platform.products.build
|
||||
- if policy(@platform.products.build).index?
|
||||
li class=('active' if contr == :products)
|
||||
= link_to t("layout.products.list_header"), platform_products_path(@platform)
|
||||
- if can? :advisories, @platform
|
||||
- if policy(@platform.advisories.build).index?
|
||||
li class=('active' if contr == :platforms && act == :advisories)
|
||||
= link_to t("layout.advisories.list_header"), advisories_platform_path(@platform)
|
||||
- if can? :update, @platform
|
||||
- if policy(@platform).update?
|
||||
li class=('active' if act == :edit && contr == :platforms)
|
||||
= link_to t("platform_menu.settings"), edit_platform_path(@platform)
|
||||
- if can? :members, @platform
|
||||
- if policy(@platform).members?
|
||||
li class=('active' if act == :members && contr == :platforms)
|
||||
= link_to t("layout.platforms.members"), members_platform_path(@platform)
|
||||
- if can? :edit, @platform
|
||||
- if policy(@platform).update?
|
||||
li class=('active' if contr == :key_pairs)
|
||||
= link_to t("layout.key_pairs.header"), platform_key_pairs_path(@platform)
|
||||
li class=('active' if contr == :tokens)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
- set_meta_tags title: t('layout.platforms.list_header')
|
||||
.row ng-controller='PlatformsCtrl'
|
||||
.col-md-6.col-md-offset-3 ng-cloak=true
|
||||
= link_to t('layout.platforms.new'), new_platform_path, class: 'btn btn-primary' if can? :create, Platform
|
||||
- if policy(:platform).create?
|
||||
a.btn.btn-primary href=new_platform_path
|
||||
= t('layout.platforms.new')
|
||||
table.table.table-hover.offset10
|
||||
thead
|
||||
tr
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
b= t('layout.platforms.distrib_type')
|
||||
.col-md-8= @platform.distrib_type
|
||||
|
||||
- if can? :clone, @platform
|
||||
- if policy(@platform).clone?
|
||||
.row
|
||||
.col-md-4
|
||||
.col-md-8
|
||||
|
|
Loading…
Reference in New Issue