ProtectedBranches model, Master permission for repo\n Allow push to protected branch for masters only

3-1-stable
Dmitriy Zaporozhets 2012-02-15 22:02:33 +02:00
parent 3a9e5a9357
commit 37224dc9c1
14 changed files with 229 additions and 53 deletions

View File

@ -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 File

@ -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 @@ class Project < ActiveRecord::Base
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 @@ class Project < ActiveRecord::Base
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 @@ class Project < ActiveRecord::Base
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 @@ end
#
# 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
#

View File

@ -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 File

@ -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 @@ class Repository
{
"Denied" => REPO_N,
"Pull" => REPO_R,
"Pull & Push" => REPO_RW
"Pull & Push" => REPO_RW,
"Master" => REPO_MASTER
}
end

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
= render "head"
= render "repositories/branches_head"
- unless @branches.empty?
%table
%thead

View File

@ -62,6 +62,7 @@ Gitlab::Application.routes.draw do
end
resources :deploy_keys
resources :protected_branches, :only => [:index, :create, :destroy]
resources :refs, :only => [], :path => "/" do
collection do

View File

@ -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 File

@ -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 @@ ActiveRecord::Schema.define(:version => 20120206170141) do
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 File

@ -64,21 +64,9 @@ module Gitlabhq
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 @@ module Gitlabhq
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

View File

@ -290,15 +290,18 @@ end
#
# 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
#

View File

@ -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