Permalink
Browse files

ProtectedBranches model, Master permission for repo\n Allow push to p…

…rotected branch for masters only
  • Loading branch information...
1 parent 3a9e5a9 commit 37224dc9c1ee80ba9030b616e2bc87bd96919e09 @dzaporozhets dzaporozhets committed Feb 15, 2012
@@ -0,0 +1,23 @@
+class ProtectedBranchesController < ApplicationController
+ before_filter :project
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :require_non_empty_project
+
+ layout "project"
+
+ def index
+ @branches = @project.protected_branches.all
+ @protected_branch = @project.protected_branches.new
+ end
+
+ def create
+ @project.protected_branches.create(params[:protected_branch])
+ redirect_to project_protected_branches_path(@project)
+ end
+
+ def destroy
+ end
+end
View
@@ -16,6 +16,7 @@ class Project < ActiveRecord::Base
has_many :snippets, :dependent => :destroy
has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key"
has_many :web_hooks, :dependent => :destroy
+ has_many :protected_branches, :dependent => :destroy
acts_as_taggable
@@ -138,6 +139,15 @@ def web_hook_data(oldrev, newrev, ref)
data
end
+ def open_branches
+ if protected_branches.empty?
+ self.repo.heads
+ else
+ pnames = protected_branches.map(&:name)
+ self.repo.heads.reject { |h| pnames.include?(h.name) }
+ end.sort_by(&:name)
+ end
+
def team_member_by_name_or_email(email = nil, name = nil)
user = users.where("email like ? or name like ?", email, name).first
users_projects.find_by_user_id(user.id) if user
@@ -210,6 +220,12 @@ def repository_writers
keys.map(&:identifier)
end
+ def repository_masters
+ keys = Key.joins({:user => :users_projects}).
+ where("users_projects.project_id = ? AND users_projects.repo_access = ?", id, Repository::REPO_MASTER)
+ keys.map(&:identifier)
+ end
+
def readers
@readers ||= users_projects.includes(:user).where(:project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).map(&:user)
end
@@ -235,7 +251,7 @@ def allow_admin_for?(user)
end
def allow_pull_for?(user)
- !users_projects.where(:user_id => user.id, :repo_access => [Repository::REPO_R, Repository::REPO_RW]).empty?
+ !users_projects.where(:user_id => user.id, :repo_access => [Repository::REPO_R, Repository::REPO_RW, Repository::REPO_MASTER]).empty?
end
def root_ref
@@ -340,15 +356,18 @@ def valid_repo?
#
# Table name: projects
#
-# id :integer not null, primary key
-# name :string(255)
-# path :string(255)
-# description :text
-# created_at :datetime
-# updated_at :datetime
-# private_flag :boolean default(TRUE), not null
-# code :string(255)
-# owner_id :integer
-# default_branch :string(255) default("master"), not null
+# id :integer not null, primary key
+# name :string(255)
+# path :string(255)
+# description :text
+# created_at :datetime
+# updated_at :datetime
+# private_flag :boolean default(TRUE), not null
+# code :string(255)
+# owner_id :integer
+# default_branch :string(255) default("master"), not null
+# issues_enabled :boolean default(TRUE), not null
+# wall_enabled :boolean default(TRUE), not null
+# merge_requests_enabled :boolean default(TRUE), not null
#
@@ -0,0 +1,29 @@
+class ProtectedBranch < ActiveRecord::Base
+ belongs_to :project
+ validates_presence_of :project_id
+ validates_presence_of :name
+
+ after_save :update_repository
+ after_destroy :update_repository
+
+ def update_repository
+ Gitlabhq::GitHost.system.new.configure do |c|
+ c.update_project(project.path, project)
+ end
+ end
+
+ def commit
+ project.commit(self.name)
+ end
+end
+# == Schema Information
+#
+# Table name: protected_branches
+#
+# id :integer not null, primary key
+# project_id :integer not null
+# name :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
View
@@ -4,6 +4,7 @@ class Repository
REPO_N = 0
REPO_R = 1
REPO_RW = 2
+ REPO_MASTER = 3
attr_accessor :project
@@ -15,7 +16,8 @@ def self.access_options
{
"Denied" => REPO_N,
"Pull" => REPO_R,
- "Pull & Push" => REPO_RW
+ "Pull & Push" => REPO_RW,
+ "Master" => REPO_MASTER
}
end
@@ -0,0 +1,39 @@
+= render "repositories/branches_head"
+
+= form_for [@project, @protected_branch] do |f|
+ -if @protected_branch.errors.any?
+ .alert-message.block-message.error
+ %ul
+ - @protected_branch.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :name
+ .input= f.select(:name, @project.open_branches.map { |br| [br.name, br.name] } , { :include_blank => "Select branch" }, { :style => "width:300px" })
+ .actions
+ = f.submit 'Add', :class => "primary btn"
+
+
+- unless @branches.empty?
+ %table
+ %thead
+ %tr
+ %th Name
+ %th Last commit
+ %tbody
+ - @branches.each do |branch|
+ %tr
+ %td
+ = link_to project_commits_path(@project, :ref => branch.name) do
+ %strong= branch.name
+ - if branch.name == @project.root_ref
+ %span.label default
+ %td
+ = link_to project_commits_path(@project, branch.commit.id) do
+ = truncate branch.commit.id.to_s, :length => 10
+ = time_ago_in_words(branch.commit.committed_date)
+ ago
+
+
+:javascript
+ $('select#protected_branch_name').chosen();
@@ -0,0 +1,9 @@
+= render "repositories/head"
+%ul.pills
+ %li{:class => ("active" if current_page?(branches_project_repository_path(@project)))}
+ = link_to branches_project_repository_path(@project) do
+ All
+ %li{:class => ("active" if current_page?(project_protected_branches_path(@project)))}
+ = link_to project_protected_branches_path(@project) do
+ Protected
+
@@ -3,7 +3,7 @@
= link_to project_repository_path(@project) do
%span
Activities
- %li{:class => "#{'active' if current_page?(branches_project_repository_path(@project)) }"}
+ %li{:class => "#{'active' if current_page?(branches_project_repository_path(@project)) || current_page?(project_protected_branches_path(@project)) }"}
= link_to branches_project_repository_path(@project) do
%span
Branches
@@ -1,4 +1,4 @@
-= render "head"
+= render "repositories/branches_head"
- unless @branches.empty?
%table
%thead
View
@@ -62,6 +62,7 @@
end
resources :deploy_keys
+ resources :protected_branches, :only => [:index, :create, :destroy]
resources :refs, :only => [], :path => "/" do
collection do
@@ -0,0 +1,10 @@
+class CreateProtectedBranches < ActiveRecord::Migration
+ def change
+ create_table :protected_branches do |t|
+ t.integer :project_id, :null => false
+ t.string :name, :null => false
+
+ t.timestamps
+ end
+ end
+end
View
@@ -11,7 +11,19 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120206170141) do
+ActiveRecord::Schema.define(:version => 20120215182305) do
+
+ create_table "features", :force => true do |t|
+ t.string "name"
+ t.string "branch_name"
+ t.integer "assignee_id"
+ t.integer "author_id"
+ t.integer "project_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "version"
+ t.integer "status", :default => 0, :null => false
+ end
create_table "issues", :force => true do |t|
t.string "title"
@@ -82,6 +94,13 @@
t.boolean "merge_requests_enabled", :default => true, :null => false
end
+ create_table "protected_branches", :force => true do |t|
+ t.integer "project_id", :null => false
+ t.string "name", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
create_table "snippets", :force => true do |t|
t.string "title"
t.text "content"
View
@@ -64,21 +64,9 @@ def delete_key(user)
def update_project(repo_name, project)
ga_repo = ::Gitolite::GitoliteAdmin.new(File.join(@local_dir,'gitolite'))
conf = ga_repo.config
-
- repo = if conf.has_repo?(repo_name)
- conf.get_repo(repo_name)
- else
- ::Gitolite::Config::Repo.new(repo_name)
- end
-
- name_readers = project.repository_readers
- name_writers = project.repository_writers
-
- repo.clean_permissions
- repo.add_permission("R", "", name_readers) unless name_readers.blank?
- repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+ repo = update_project_config(project, conf)
conf.add_repo(repo, true)
-
+
ga_repo.save
end
@@ -89,25 +77,43 @@ def update_projects(projects)
conf = ga_repo.config
projects.each do |project|
- repo_name = project.path
-
- repo = if conf.has_repo?(repo_name)
- conf.get_repo(repo_name)
- else
- ::Gitolite::Config::Repo.new(repo_name)
- end
-
- name_readers = project.repository_readers
- name_writers = project.repository_writers
-
- repo.clean_permissions
- repo.add_permission("R", "", name_readers) unless name_readers.blank?
- repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+ repo = update_project_config(project, conf)
conf.add_repo(repo, true)
end
ga_repo.save
end
+ def update_project_config(project, conf)
+ repo_name = project.path
+
+ repo = if conf.has_repo?(repo_name)
+ conf.get_repo(repo_name)
+ else
+ ::Gitolite::Config::Repo.new(repo_name)
+ end
+
+ name_readers = project.repository_readers
+ name_writers = project.repository_writers
+ name_masters = project.repository_masters
+
+ pr_br = project.protected_branches.map(&:name).join(" ")
+
+ repo.clean_permissions
+
+ # Deny access to protected branches for writers
+ unless name_writers.blank? || pr_br.blank?
+ repo.add_permission("-", pr_br, name_writers)
+ end
+
+ # Add read permissions
+ repo.add_permission("R", "", name_readers) unless name_readers.blank?
+
+ # Add write permissions
+ repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
+ repo.add_permission("RW+", "", name_masters) unless name_masters.blank?
+
+ repo
+ end
end
end
@@ -290,15 +290,18 @@
#
# Table name: projects
#
-# id :integer not null, primary key
-# name :string(255)
-# path :string(255)
-# description :text
-# created_at :datetime
-# updated_at :datetime
-# private_flag :boolean default(TRUE), not null
-# code :string(255)
-# owner_id :integer
-# default_branch :string(255) default("master"), not null
+# id :integer not null, primary key
+# name :string(255)
+# path :string(255)
+# description :text
+# created_at :datetime
+# updated_at :datetime
+# private_flag :boolean default(TRUE), not null
+# code :string(255)
+# owner_id :integer
+# default_branch :string(255) default("master"), not null
+# issues_enabled :boolean default(TRUE), not null
+# wall_enabled :boolean default(TRUE), not null
+# merge_requests_enabled :boolean default(TRUE), not null
#
@@ -0,0 +1,16 @@
+# == Schema Information
+#
+# Table name: protected_branches
+#
+# id :integer not null, primary key
+# project_id :integer not null
+# name :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
+require 'spec_helper'
+
+describe ProtectedBranch do
+ pending "add some examples to (or delete) #{__FILE__}"
+end

0 comments on commit 37224dc

Please sign in to comment.