This commit is contained in:
Vokhmin Alexey V 2015-03-20 02:31:41 +03:00
parent e829d35a89
commit d4d8f75f12
18 changed files with 209 additions and 93 deletions

View File

@ -20,7 +20,7 @@ class AdvisoriesController < ApplicationController
end
def search
authorize :advisories, :index?
authorize :advisories
@advisory = Advisory.by_update_type(params[:bl_type]).search_by_id(params[:query]).first
if @advisory.nil?
render nothing: true, status: 404

View File

@ -1,8 +1,16 @@
class Api::V1::BuildListsController < Api::V1::BaseController
before_action :authenticate_user!
skip_before_action :authenticate_user!, only: [:show, :index] if APP_CONFIG['anonymous_access']
# load_and_authorize_resource :build_list, only: [:show, :create, :cancel, :publish, :reject_publish, :create_container, :publish_into_testing, :rerun_tests]
before_action :load_build_list, only: %i(
cancel
create
create_container
publish
publish_into_testing
reject_publish
rerun_tests
show
)
skip_before_action :authenticate_user!, only: %i(show index) if APP_CONFIG['anonymous_access']
def show
authorize @build_list
@ -38,35 +46,45 @@ class Api::V1::BuildListsController < Api::V1::BaseController
end
def cancel
authorize @build_list, :create?
authorize @build_list
render_json :cancel
end
def publish
authorize @build_list
@build_list.publisher = current_user
render_json :publish
end
def reject_publish
authorize @build_list
@build_list.publisher = current_user
render_json :reject_publish
end
def create_container
authorize @build_list
render_json :create_container, :publish_container
end
def rerun_tests
authorize @build_list
render_json :rerun_tests
end
def publish_into_testing
authorize @build_list
@build_list.publisher = current_user
render_json :publish_into_testing
end
private
# Private: before_action hook which loads BuidList.
def load_build_list
@build_list = BuildList.find params[:id]
end
def render_json(action_name, action_method = nil)
if @build_list.try("can_#{action_name}?") && @build_list.send(action_method || action_name)
render_json_response @build_list, t("layout.build_lists.#{action_name}_success")

View File

@ -0,0 +1,45 @@
module Api
module V1
module Issueable
extend ActiveSupport::Concern
protected
# Private: before_action hook which loads Group.
def load_group
authorize @group = Group.find(params[:id]), :show?
end
# Private: before_action hook which loads Project.
def load_project
authorize @project = Project.find(params[:project_id]), :show?
end
# Private: before_action hook which loads Issue.
def load_issue
authorize @issue = @project.issues.find_by(serial_id: params[:id]), :show?
end
# Private: Get membered projects.
#
# Returns the ActiveRecord::Relation instance.
def membered_projects
@membered_projects ||= ProjectPolicy::Scope.new(current_user, Project).membered
end
# Private: Get project ids which available for current user.
#
# Returns the Array of project ids.
def get_all_project_ids(default_project_ids)
project_ids = []
if %w(created all).include? params[:filter]
# add own issues
project_ids = Project.opened.joins(:issues).
where(issues: {user_id: current_user.id}).
pluck('projects.id')
end
project_ids | default_project_ids
end
end
end
end

View File

@ -1,11 +1,13 @@
class Api::V1::IssuesController < Api::V1::BaseController
before_action :authenticate_user!
skip_before_action :authenticate_user!, only: [:index, :group_index, :show] if APP_CONFIG['anonymous_access']
include Api::V1::Issueable
load_and_authorize_resource :group, only: :group_index, find_by: :id, parent: false
load_and_authorize_resource :project
skip_load_and_authorize_resource :project, only: [:all_index, :user_index, :group_index]
load_and_authorize_resource :issue, through: :project, find_by: :serial_id, only: [:show, :update, :create, :index]
before_action :authenticate_user!
skip_before_action :authenticate_user!, only: %i(index group_index show) if APP_CONFIG['anonymous_access']
before_action :load_group, only: :group_index
before_action :load_project
skip_before_action :load_project, only: %i(all_index user_index group_index)
before_action :load_issue, only: %i(show update create index)
def index
@issues = @project.issues
@ -13,12 +15,14 @@ class Api::V1::IssuesController < Api::V1::BaseController
end
def all_index
project_ids = get_all_project_ids Project.accessible_by(current_ability, :membered).pluck(:id)
authorize :issue, :index?
project_ids = get_all_project_ids membered_projects.pluck(:id)
@issues = Issue.where(project_id: project_ids)
render_issues_list
end
def user_index
authorize :issue, :index?
project_ids = get_all_project_ids current_user.projects.pluck(:id)
@issues = Issue.where(project_id: project_ids)
render_issues_list
@ -26,7 +30,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
def group_index
project_ids = @group.projects.pluck(:id)
project_ids = Project.accessible_by(current_ability, :membered).where(id: project_ids).pluck(:id)
project_ids = membered_projects.where(id: project_ids).pluck(:id)
@issues = Issue.where(project_id: project_ids)
render_issues_list
end
@ -40,6 +44,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
end
def create
@issue = @project.issues.new(params[:issue])
@issue.user = current_user
@issue.assignee = nil if cannot?(:write, @project)
create_subject @issue
@ -94,7 +99,7 @@ class Api::V1::IssuesController < Api::V1::BaseController
end
if params[:labels].present?
labels = params[:labels].split(',').map {|e| e.strip}.select {|e| e.present?}
labels = params[:labels].split(',').map(&:strip).select(&:present?)
@issues = @issues.where('labels.name IN (?)', labels)
end
@ -110,13 +115,4 @@ class Api::V1::IssuesController < Api::V1::BaseController
end
end
def get_all_project_ids default_project_ids
project_ids = []
if ['created', 'all'].include? params[:filter]
# add own issues
project_ids = Project.accessible_by(current_ability, :show).joins(:issues).
where(issues: {user_id: current_user.id}).pluck('projects.id')
end
project_ids |= default_project_ids
end
end

View File

@ -3,30 +3,25 @@ class Api::V1::ProjectsController < Api::V1::BaseController
before_action :authenticate_user!
skip_before_action :authenticate_user!, only: [:get_id, :show, :refs_list] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :project
before_action :load_project
def index
@projects = Project.accessible_by(current_ability, :membered)
.paginate(paginate_params)
authorize :project
@projects = ProjectPolicy::Scope.new(current_user, Project).
membered.paginate(paginate_params)
respond_to :json
end
def get_id
if @project = Project.find_by_owner_and_name(params[:owner], params[:name])
authorize @project, :show?
else
raise ActiveRecord::RecordNotFound
end
authorize @project = Project.find_by_owner_and_name!(params[:owner], params[:name])
respond_to :json
end
def show
authorize @project, :show?
respond_to :json
end
def refs_list
authorize @project, :show?
@refs = @project.repo.branches + @project.repo.tags.select{ |t| t.commit }
respond_to :json
end
@ -40,11 +35,11 @@ class Api::V1::ProjectsController < Api::V1::BaseController
end
def create
p_params = params[:project] || {}
owner_type = p_params[:owner_type]
if owner_type.present? && %w(User Group).include?(owner_type)
@project.owner = owner_type.constantize.
where(id: p_params[:owner_id]).first
@project = Project.new(params[:project])
p_params = params[:project] || {}
owner_type = %w(User Group).find{ |t| t == p_params[:owner_type] }
if owner_type.present?
@project.owner = owner_type.constantize.find_by(id: p_params[:owner_id])
else
@project.owner = nil
end
@ -82,4 +77,11 @@ class Api::V1::ProjectsController < Api::V1::BaseController
def alias
fork(true)
end
private
# Private: before_action hook which loads Project.
def load_project
authorize @project = Project.find(params[:id]) if params[:id]
end
end

View File

@ -1,13 +1,13 @@
class Api::V1::PullRequestsController < Api::V1::BaseController
respond_to :json
include Api::V1::Issueable
before_action :authenticate_user!
skip_before_action :authenticate_user!, only: [:show, :index, :group_index, :commits, :files] if APP_CONFIG['anonymous_access']
skip_before_action :authenticate_user!, only: %i(show index group_index commits files) if APP_CONFIG['anonymous_access']
load_resource :group, only: :group_index, find_by: :id, parent: false
load_resource :project
load_resource :issue, through: :project, find_by: :serial_id, parent: false, only: [:show, :index, :commits, :files, :merge, :update]
load_and_authorize_resource instance_name: :pull, through: :issue, singleton: true, only: [:show, :index, :commits, :files, :merge, :update]
before_action :load_group, only: :group_index
before_action :load_project
before_action :load_issue, only: %i(show index commits files merge update)
before_action :load_pull, only: %i(show index commits files merge update)
def index
@pulls = @project.pull_requests
@ -16,13 +16,15 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
end
def all_index
project_ids = get_all_project_ids Project.accessible_by(current_ability, :membered).pluck(:id)
authorize :pull_request, :index?
project_ids = get_all_project_ids membered_projects.pluck(:id)
@pulls = PullRequest.where('pull_requests.to_project_id IN (?)', project_ids)
@pulls_url = api_v1_pull_requests_path format: :json
render_pulls_list
end
def user_index
authorize :pull_request, :index?
project_ids = get_all_project_ids current_user.projects.pluck(:id)
@pulls = PullRequest.where('pull_requests.to_project_id IN (?)', project_ids)
@pulls_url = pull_requests_api_v1_user_path format: :json
@ -31,7 +33,7 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
def group_index
project_ids = @group.projects.pluck(:id)
project_ids = Project.accessible_by(current_ability, :membered).where(id: project_ids).pluck(:id)
project_ids = membered_projects.where(id: project_ids).pluck(:id)
@pulls = PullRequest.where(to_project_id: project_ids)
@pulls_url = pull_requests_api_v1_group_path
render_pulls_list
@ -43,7 +45,7 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
end
def create
from_project = Project.find(pull_params[:from_project_id]) if pull_params[:from_project_id].present?
from_project = Project.find_by(id: pull_params[:from_project_id])
from_project ||= @project
authorize from_project, :show?
@ -56,6 +58,7 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
@pull.issue.new_pull_request = true
render_validation_error(@pull, "#{@pull.class.name} has not been created") && return unless @pull.valid?
authorize @pull
@pull.save # set pull id
@pull.reload
@pull.check(false) # don't make event transaction
@ -71,13 +74,13 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
def update
@pull = @project.pull_requests.includes(:issue).where(issues: {serial_id: params[:id]}).first
authorize! :update, @pull
authorize @pull
if pull_params.present?
attrs = pull_params.slice(:title, :body)
attrs.merge!(assignee_id: pull_params[:assignee_id]) if policy(@project).write?
if (action = pull_params[:status]) && %w(close reopen).include?(pull_params[:status])
if action = %w(close reopen).find{ |s| s == pull_params[:status] }
if @pull.send("can_#{action}?")
@pull.set_user_and_time current_user
need_check = true if action == 'reopen' && @pull.valid?
@ -96,16 +99,19 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
end
def commits
authorize @pull
@commits = @pull.repo.commits_between(@pull.to_commit, @pull.from_commit).paginate(paginate_params)
respond_to :json
end
def files
authorize @pull
@stats = @pull.diff_stats.zip(@pull.diff).paginate(paginate_params)
respond_to :json
end
def merge
authorize @pull
class_name = @pull.class.name
if @pull.merge!(current_user)
render_json_response @pull, "#{class_name} has been merged successfully"
@ -116,6 +122,11 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
private
# Private: before_action hook which loads PullRequest.
def load_pull
authorize @pull = @issue.pull_request, :show?
end
def render_pulls_list
@pulls = @pulls.includes(issue: [:user, :assignee])
if params[:status] == 'closed'
@ -159,17 +170,6 @@ class Api::V1::PullRequestsController < Api::V1::BaseController
end
end
def get_all_project_ids default_project_ids
project_ids = []
if ['created', 'all'].include? params[:filter]
# add own pulls
project_ids = Project.accessible_by(current_ability, :show).joins(:issues).
where(issues: {user_id: current_user.id}).pluck('projects.id')
end
project_ids |= default_project_ids
end
def pull_params
@pull_params ||= params[:pull_request] || {}
end

View File

@ -4,7 +4,8 @@ class Api::V1::RepositoriesController < Api::V1::BaseController
before_action :authenticate_user!
skip_before_action :authenticate_user!, only: [:show, :projects] if APP_CONFIG['anonymous_access']
load_and_authorize_resource :repository, through: :platform, shallow: true
before_action :load_platform
before_action :load_repository
def show
respond_to :json
@ -110,4 +111,16 @@ class Api::V1::RepositoriesController < Api::V1::BaseController
end
end
private
# Private: before_action hook which loads Platform.
def load_platform
authorize @platform = Platform.find_cached(params[:platform_id]), :show?
end
# Private: before_action hook which loads Repository.
def load_repository
authorize @repository = @platform.repositories.find(params[:id]) if params[:id]
end
end

View File

@ -19,6 +19,7 @@ class ApplicationController < ActionController::Base
only: [:create, :destroy, :open_id, :cancel, :publish, :change_visibility] # :update
before_action :banned?
after_action -> { EventLog.current_controller = nil }
after_action :verify_authorized
helper_method :get_owner
@ -46,12 +47,11 @@ class ApplicationController < ActionController::Base
# 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
if user_signed_in? && current_user.is_banned?
sign_out current_user
flash[:error] = I18n.t('devise.failure.locked')
redirect_to root_path
end
end
# For this example, we are simply using token authentication

View File

@ -1,5 +1,6 @@
class AutocompletesController < ApplicationController
before_action :authenticate_user!
before_action :authenticate_user!
skip_after_action :verify_authorized
def autocomplete_user_uname
results = User.opened.search(params[:query]).search_order.limit(5)
@ -13,7 +14,8 @@ class AutocompletesController < ApplicationController
end
def autocomplete_extra_build_list
bl = BuildList.for_extra_build_lists(params[:term], current_ability, save_to_platform).first
bl = BuildListPolicy::Scope.new(current_user, BuildList).read.
for_extra_build_lists(params[:term], save_to_platform).first
results << { :id => bl.id,
:value => bl.id,
:label => "#{bl.id} (#{bl.project.name} - #{bl.arch.name})",
@ -35,10 +37,10 @@ class AutocompletesController < ApplicationController
def autocomplete_extra_repositories
# Only personal and build for platform repositories can be attached to the build
Platform.includes(:repositories).search(params[:term]).search_order
.accessible_by(current_ability, :read).limit(5)
.where("platforms.platform_type = 'personal' OR platforms.id = ?",
params[:build_for_platform_id].to_i).each do |platform|
platforms = PlatformPolicy::Scope.new(current_user, Platform).related.
includes(:repositories).search(params[:term]).search_order.limit(5).
where("platforms.platform_type = 'personal' OR platforms.id = ?", params[:build_for_platform_id])
platforms.each do |platform|
platform.repositories.each do |repository|
results <<
{
@ -56,7 +58,7 @@ class AutocompletesController < ApplicationController
protected
def save_to_platform
@save_to_platform ||= Platform.find(params[:platform_id])
@save_to_platform ||= Platform.find_cached(params[:platform_id])
end
def results

View File

@ -4,6 +4,7 @@ class Groups::BaseController < ApplicationController
protected
# Private: before_action hook which loads Group.
def find_group
if group_id = params[:uname] || params[:group_id] || params[:id]
@group = Group.find_by_insensitive_uname! group_id

View File

@ -1,5 +1,5 @@
class Groups::MembersController < Groups::BaseController
before_action -> { authorize @group, :update? }
before_action -> { authorize @group, :manage_members? }
def index
@members = @group.members.order(:uname) - [@group.owner]
@ -25,7 +25,7 @@ class Groups::MembersController < Groups::BaseController
end
def add
@user = User.where(id: params[:member_id]).first
@user = User.find_by(id: params[:member_id])
if !@user
flash[:error] = t("flash.collaborators.wrong_user", uname: params[:user_uname])
elsif @group.add_member(@user, params[:role])

View File

@ -2,10 +2,10 @@ class Groups::ProfileController < Groups::BaseController
include AvatarHelper
include PaginateHelper
# load_and_authorize_resource class: Group, instance_name: 'group'
skip_before_action :authenticate_user!, only: :show if APP_CONFIG['anonymous_access']
def index
authorize :group
@groups = current_user.groups.paginate(page: params[:group_page]) # accessible_by(current_ability)
@groups = @groups.search(params[:query]) if params[:query].present?
end
@ -34,14 +34,15 @@ class Groups::ProfileController < Groups::BaseController
end
def new
@group = current_user.own_groups.build
authorize @group = current_user.own_groups.build
end
def edit
authorize @group
end
def create
@group = current_user.own_groups.new params[:group]
authorize @group = current_user.own_groups.build(params[:group])
if @group.save
flash[:notice] = t('flash.group.saved')
redirect_to group_path(@group)
@ -53,6 +54,7 @@ class Groups::ProfileController < Groups::BaseController
end
def update
authorize @group
if @group.update_attributes(params[:group])
update_avatar(@group, params)
flash[:notice] = t('flash.group.saved')
@ -64,12 +66,14 @@ class Groups::ProfileController < Groups::BaseController
end
def destroy
authorize @group
@group.destroy
flash[:notice] = t("flash.group.destroyed")
redirect_to groups_path
end
def remove_user
authorize @group
Relation.by_actor(current_user).by_target(@group).destroy_all
redirect_to groups_path
end

View File

@ -131,9 +131,8 @@ class BuildList < ActiveRecord::Base
HUMAN_STATUSES.freeze
scope :recent, -> { order(updated_at: :desc) }
scope :for_extra_build_lists, ->(ids, current_ability, save_to_platform) {
s = all
s = s.where(id: ids).published_container.accessible_by(current_ability, :read)
scope :for_extra_build_lists, ->(ids, save_to_platform) {
s = s.where(id: ids)
s = s.where(save_to_platform_id: save_to_platform.id) if save_to_platform && save_to_platform.main?
s
}
@ -745,7 +744,8 @@ class BuildList < ActiveRecord::Base
extra_build_lists.flatten!
end
return if extra_build_lists.blank?
bls = BuildList.for_extra_build_lists(extra_build_lists, current_ability, save_to_platform)
bls = BuildListPolicy::Scope.new(user, BuildList).read.
for_extra_build_lists(extra_build_lists, save_to_platform)
if save_to_platform
if save_to_platform.distrib_type == 'rhel'
bls = bls.where('

View File

@ -3,9 +3,7 @@ class AdvisoryPolicy < ApplicationPolicy
def index?
true
end
def show?
true
end
alias_method :search?, :index?
alias_method :show?, :index?
end

View File

@ -1,5 +1,9 @@
class BuildListPolicy < ApplicationPolicy
def index?
true
end
def show?
record.user_id == user.id || policy(record.project).show?
end
@ -48,5 +52,39 @@ class BuildListPolicy < ApplicationPolicy
policy(record.project).write?
end
class Scope < Scope
def read
policy = Pundit.policy!(user, :build_list)
scope = scope.joins(:project)
scope.where <<-SQL, { user_id: user.id, user_group_ids: policy.user_group_ids }
(
build_lists.user_id = :user_id
) OR (
projects.visibility = 'open'
) OR (
projects.owner_type = 'User' AND projects.owner_id = :user_id
) OR (
projects.owner_type = 'Group' AND projects.owner_id IN (:user_group_ids)
) OR (
projects.id = ANY (
ARRAY (
SELECT target_id
FROM relations
INNER JOIN projects ON projects.id = relations.target_id
WHERE relations.target_type = 'Project' AND
(
projects.owner_type = 'User' AND projects.owner_id != :user_id OR
projects.owner_type = 'Group' AND projects.owner_id NOT IN (:user_group_ids)
) AND (
relations.actor_type = 'User' AND relations.actor_id = :user_id OR
relations.actor_type = 'Group' AND relations.actor_id IN (:user_group_ids)
)
)
)
)
SQL
end
end
end

View File

@ -23,11 +23,12 @@ class GroupPolicy < ApplicationPolicy
def update?
owner? || local_admin?
end
alias_method :add_member?, :update?
alias_method :manage_members?, :update?
alias_method :members?, :update?
alias_method :add_member?, :update?
alias_method :remove_member?, :update?
alias_method :remove_members?, :update?
alias_method :remove_user?, :update?
alias_method :update_member?, :update?
def destroy?

View File

@ -1,7 +1,8 @@
class IssuePolicy < ApplicationPolicy
def index?
record.project.has_issues?
# record.project.has_issues?
true
end
def show?

View File

@ -16,7 +16,4 @@ class UserPolicy < ApplicationPolicy
record == user
end
def banned?
!is_banned?
end
end