Skip to content
Snippets Groups Projects
Commit eb1004f7 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Refactor abilities. Added ProjectUpdate context. Fixed few bugs with namespaces

parent a1ffc673
No related branches found
No related tags found
No related merge requests found
Showing
with 127 additions and 53 deletions
class ProjectUpdateContext < BaseContext
def execute(role = :default)
namespace_id = params[:project].delete(:namespace_id)
if namespace_id.present?
if namespace_id == Namespace.global_id
if project.namespace.present?
# Transfer to global namespace from anyone
project.transfer(nil)
end
elsif namespace_id.to_i != project.namespace_id
# Transfer to someone namespace
namespace = Namespace.find(namespace_id)
project.transfer(namespace)
end
end
project.update_attributes(params[:project], as: role)
end
end
Loading
Loading
@@ -24,13 +24,9 @@ class Admin::ProjectsController < AdminController
end
 
def update
owner_id = params[:project].delete(:owner_id)
status = ProjectUpdateContext.new(project, current_user, params).execute(:admin)
 
if owner_id
@project.owner = User.find(owner_id)
end
if @project.update_attributes(params[:project], as: :admin)
if status
redirect_to [:admin, @project], notice: 'Project was successfully updated.'
else
render action: "edit"
Loading
Loading
Loading
Loading
@@ -2,6 +2,7 @@ class ApplicationController < ActionController::Base
before_filter :authenticate_user!
before_filter :reject_blocked!
before_filter :set_current_user_for_observers
before_filter :add_abilities
before_filter :dev_tools if Rails.env == 'development'
 
protect_from_forgery
Loading
Loading
@@ -65,11 +66,17 @@ class ApplicationController < ActionController::Base
def project
id = params[:project_id] || params[:id]
 
@project ||= current_user.projects.find_with_namespace(id)
@project || render_404
@project = Project.find_with_namespace(id)
if @project and can?(current_user, :read_project, @project)
@project
else
@project = nil
render_404
end
end
 
def add_project_abilities
def add_abilities
abilities << Ability
end
 
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ class DashboardController < ApplicationController
before_filter :event_filter, only: :index
 
def index
@groups = Group.where(id: current_user.projects.pluck(:namespace_id))
@groups = current_user.accessed_groups
@projects = @projects.page(params[:page]).per(30)
@events = Event.in_projects(current_user.project_ids)
@events = @event_filter.apply_filter(@events)
Loading
Loading
Loading
Loading
@@ -4,7 +4,6 @@ class GroupsController < ApplicationController
 
before_filter :group
before_filter :projects
before_filter :add_project_abilities
 
def show
@events = Event.in_projects(project_ids).limit(20).offset(params[:offset] || 0)
Loading
Loading
@@ -45,7 +44,7 @@ class GroupsController < ApplicationController
end
 
def people
@users = group.users.all
@users = group.users
end
 
protected
Loading
Loading
@@ -55,7 +54,11 @@ class GroupsController < ApplicationController
end
 
def projects
@projects ||= current_user.projects_sorted_by_activity.where(namespace_id: @group.id)
@projects ||= if can?(current_user, :manage_group, @group)
@group.projects.all
else
current_user.projects_sorted_by_activity.where(namespace_id: @group.id)
end
end
 
def project_ids
Loading
Loading
class ProjectResourceController < ApplicationController
before_filter :project
# Authorize
before_filter :add_project_abilities
end
Loading
Loading
@@ -34,20 +34,10 @@ class ProjectsController < ProjectResourceController
end
 
def update
if params[:project].has_key?(:namespace_id)
namespace_id = params[:project].delete(:namespace_id)
if namespace_id == Namespace.global_id and project.namespace.present?
# Transfer to global namespace from anyone
project.transfer(nil)
elsif namespace_id.present? and namespace_id.to_i != project.namespace_id
# Transfer to someone namespace
namespace = Namespace.find(namespace_id)
project.transfer(namespace)
end
end
status = ProjectUpdateContext.new(project, current_user, params).execute
 
respond_to do |format|
if project.update_attributes(params[:project])
if status
flash[:notice] = 'Project was successfully updated.'
format.html { redirect_to edit_project_path(project), notice: 'Project was successfully updated.' }
format.js
Loading
Loading
Loading
Loading
@@ -15,7 +15,37 @@ class Ability
def project_abilities(user, project)
rules = []
 
rules << [
# Rules based on role in project
if project.master_access_for?(user)
# TODO: replace with master rules.
# Only allow project administration for owners
rules << project_admin_rules
elsif project.dev_access_for?(user)
rules << project_dev_rules
elsif project.report_access_for?(user)
rules << project_report_rules
elsif project.guest_access_for?(user)
rules << project_guest_rules
end
# If user own project namespace (Ex. group owner or account owner)
if project.namespace && project.namespace.owner == user
rules << project_admin_rules
end
# If user was set as direct project owner
if project.owner == user
rules << project_admin_rules
end
rules.flatten
end
def project_guest_rules
[
:read_project,
:read_wiki,
:read_issue,
Loading
Loading
@@ -27,28 +57,30 @@ class Ability
:write_project,
:write_issue,
:write_note
] if project.guest_access_for?(user)
]
end
 
rules << [
def project_report_rules
project_guest_rules + [
:download_code,
:write_merge_request,
:write_snippet
] if project.report_access_for?(user)
]
end
 
rules << [
def project_dev_rules
project_report_rules + [
:write_wiki,
:push_code
] if project.dev_access_for?(user)
rules << [
:push_code_to_protected_branches
] if project.master_access_for?(user)
]
end
 
rules << [
def project_master_rules
project_dev_rules + [
:push_code_to_protected_branches,
:modify_issue,
:modify_snippet,
:modify_merge_request,
:admin_project,
:admin_issue,
:admin_milestone,
:admin_snippet,
Loading
Loading
@@ -57,9 +89,13 @@ class Ability
:admin_note,
:accept_mr,
:admin_wiki
] if project.master_access_for?(user) || project.owner == user
]
end
 
rules.flatten
def project_admin_rules
project_master_rules + [
:admin_project
]
end
 
def group_abilities user, group
Loading
Loading
Loading
Loading
@@ -13,7 +13,9 @@
 
class Group < Namespace
def users
User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq
users = User.joins(:users_projects).where(users_projects: {project_id: project_ids})
users = users << owner
users.uniq
end
 
def human_name
Loading
Loading
Loading
Loading
@@ -53,12 +53,14 @@ class Namespace < ActiveRecord::Base
end
 
def move_dir
old_path = File.join(Gitlab.config.git_base_path, path_was)
new_path = File.join(Gitlab.config.git_base_path, path)
if File.exists?(new_path)
raise "Already exists"
if path_changed?
old_path = File.join(Gitlab.config.git_base_path, path_was)
new_path = File.join(Gitlab.config.git_base_path, path)
if File.exists?(new_path)
raise "Already exists"
end
system("mv #{old_path} #{new_path}")
end
system("mv #{old_path} #{new_path}")
end
 
def rm_dir
Loading
Loading
Loading
Loading
@@ -29,7 +29,7 @@ class Project < ActiveRecord::Base
attr_accessible :name, :path, :description, :default_branch, :issues_enabled,
:wall_enabled, :merge_requests_enabled, :wiki_enabled, as: [:default, :admin]
 
attr_accessible :namespace_id, as: :admin
attr_accessible :namespace_id, :owner_id, as: :admin
 
attr_accessor :error_code
 
Loading
Loading
Loading
Loading
@@ -123,4 +123,11 @@ class User < ActiveRecord::Base
self.password = self.password_confirmation = Devise.friendly_token.first(8)
end
end
def accessed_groups
@accessed_groups ||= begin
groups = Group.where(id: self.projects.pluck(:namespace_id)).all
groups + self.groups
end
end
end
Loading
Loading
@@ -22,7 +22,7 @@
- unless project.new_record?
.clearfix
= f.label :namespace_id
.input= f.select :namespace_id, namespaces_options, {}, {class: 'chosen'}
.input= f.select :namespace_id, namespaces_options(@project.namespace_id), {}, {class: 'chosen'}
 
.clearfix
= f.label :owner_id
Loading
Loading
%h1 403
%h1.http_status_code 403
%h3.page_title Access Denied
%hr
%p You are not allowed to access this page.
Loading
Loading
Loading
Loading
@@ -10,7 +10,7 @@
- if @events.any?
.content_list= render @events
- else
%h4.nothing_here_message Projects activity will be displayed here
%p.nothing_here_message Projects activity will be displayed here
.loading.hide
.side
= render "projects", projects: @projects
Loading
Loading
Group.seed(:id, [
{ id: 100, name: "Gitlab", path: 'gitlab', owner_id: 1},
{ id: 101, name: "Rails", path: 'rails', owner_id: 1 },
{ id: 102, name: "KDE", path: 'kde', owner_id: 1 }
])
Project.seed(:id, [
{ id: 10, name: "kdebase", path: "kdebase", owner_id: 1, namespace_id: 102 },
{ id: 11, name: "kdelibs", path: "kdelibs", owner_id: 1, namespace_id: 102 },
{ id: 12, name: "amarok", path: "amarok", owner_id: 1, namespace_id: 102 }
])
Loading
Loading
@@ -24,7 +24,7 @@ describe Group do
it { should validate_presence_of :owner }
 
describe :users do
it { group.users.should == [] }
it { group.users.should == [group.owner] }
end
 
describe :human_name do
Loading
Loading
Loading
Loading
@@ -55,9 +55,10 @@ describe Namespace do
describe :move_dir do
before do
@namespace = create :namespace
@namespace.stub(path_changed?: true)
end
 
it "should raise error when called directly" do
it "should raise error when dirtory exists" do
expect { @namespace.move_dir }.to raise_error("Already exists")
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment