Commit 37224dc9 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

ProtectedBranches model, Master permission for repo\n Allow push to protected...

ProtectedBranches model, Master permission for repo\n Allow push to protected branch for masters only
parent 3a9e5a93
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
...@@ -16,6 +16,7 @@ class Project < ActiveRecord::Base ...@@ -16,6 +16,7 @@ class Project < ActiveRecord::Base
has_many :snippets, :dependent => :destroy has_many :snippets, :dependent => :destroy
has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key" has_many :deploy_keys, :dependent => :destroy, :foreign_key => "project_id", :class_name => "Key"
has_many :web_hooks, :dependent => :destroy has_many :web_hooks, :dependent => :destroy
has_many :protected_branches, :dependent => :destroy
acts_as_taggable acts_as_taggable
...@@ -138,6 +139,15 @@ class Project < ActiveRecord::Base ...@@ -138,6 +139,15 @@ class Project < ActiveRecord::Base
data data
end 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) def team_member_by_name_or_email(email = nil, name = nil)
user = users.where("email like ? or name like ?", email, name).first user = users.where("email like ? or name like ?", email, name).first
users_projects.find_by_user_id(user.id) if user users_projects.find_by_user_id(user.id) if user
...@@ -210,6 +220,12 @@ class Project < ActiveRecord::Base ...@@ -210,6 +220,12 @@ class Project < ActiveRecord::Base
keys.map(&:identifier) keys.map(&:identifier)
end 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 def readers
@readers ||= users_projects.includes(:user).where(:project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).map(&:user) @readers ||= users_projects.includes(:user).where(:project_access => [PROJECT_R, PROJECT_RW, PROJECT_RWA]).map(&:user)
end end
...@@ -235,7 +251,7 @@ class Project < ActiveRecord::Base ...@@ -235,7 +251,7 @@ class Project < ActiveRecord::Base
end end
def allow_pull_for?(user) 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 end
def root_ref def root_ref
...@@ -350,5 +366,8 @@ end ...@@ -350,5 +366,8 @@ end
# code :string(255) # code :string(255)
# owner_id :integer # owner_id :integer
# default_branch :string(255) default("master"), not null # 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
# #
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
#
...@@ -4,6 +4,7 @@ class Repository ...@@ -4,6 +4,7 @@ class Repository
REPO_N = 0 REPO_N = 0
REPO_R = 1 REPO_R = 1
REPO_RW = 2 REPO_RW = 2
REPO_MASTER = 3
attr_accessor :project attr_accessor :project
...@@ -15,7 +16,8 @@ class Repository ...@@ -15,7 +16,8 @@ class Repository
{ {
"Denied" => REPO_N, "Denied" => REPO_N,
"Pull" => REPO_R, "Pull" => REPO_R,
"Pull & Push" => REPO_RW "Pull & Push" => REPO_RW,
"Master" => REPO_MASTER
} }
end end
......
= 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();
= 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 @@ ...@@ -3,7 +3,7 @@
= link_to project_repository_path(@project) do = link_to project_repository_path(@project) do
%span %span
Activities 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 = link_to branches_project_repository_path(@project) do
%span %span
Branches Branches
......
= render "head" = render "repositories/branches_head"
- unless @branches.empty? - unless @branches.empty?
%table %table
%thead %thead
......
...@@ -62,6 +62,7 @@ Gitlab::Application.routes.draw do ...@@ -62,6 +62,7 @@ Gitlab::Application.routes.draw do
end end
resources :deploy_keys resources :deploy_keys
resources :protected_branches, :only => [:index, :create, :destroy]
resources :refs, :only => [], :path => "/" do resources :refs, :only => [], :path => "/" do
collection do collection do
......
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
...@@ -11,7 +11,19 @@ ...@@ -11,7 +11,19 @@
# #
# It's strongly recommended to check this file into your version control system. # 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| create_table "issues", :force => true do |t|
t.string "title" t.string "title"
...@@ -82,6 +94,13 @@ ActiveRecord::Schema.define(:version => 20120206170141) do ...@@ -82,6 +94,13 @@ ActiveRecord::Schema.define(:version => 20120206170141) do
t.boolean "merge_requests_enabled", :default => true, :null => false t.boolean "merge_requests_enabled", :default => true, :null => false
end 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| create_table "snippets", :force => true do |t|
t.string "title" t.string "title"
t.text "content" t.text "content"
......
...@@ -64,19 +64,7 @@ module Gitlabhq ...@@ -64,19 +64,7 @@ module Gitlabhq
def update_project(repo_name, project) def update_project(repo_name, project)
ga_repo = ::Gitolite::GitoliteAdmin.new(File.join(@local_dir,'gitolite')) ga_repo = ::Gitolite::GitoliteAdmin.new(File.join(@local_dir,'gitolite'))
conf = ga_repo.config conf = ga_repo.config
repo = update_project_config(project, conf)
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?
conf.add_repo(repo, true) conf.add_repo(repo, true)
ga_repo.save ga_repo.save
...@@ -89,6 +77,14 @@ module Gitlabhq ...@@ -89,6 +77,14 @@ module Gitlabhq
conf = ga_repo.config conf = ga_repo.config
projects.each do |project| projects.each do |project|
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_name = project.path
repo = if conf.has_repo?(repo_name) repo = if conf.has_repo?(repo_name)
...@@ -99,15 +95,25 @@ module Gitlabhq ...@@ -99,15 +95,25 @@ module Gitlabhq
name_readers = project.repository_readers name_readers = project.repository_readers
name_writers = project.repository_writers name_writers = project.repository_writers
name_masters = project.repository_masters
pr_br = project.protected_branches.map(&:name).join(" ")
repo.clean_permissions 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? 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_writers) unless name_writers.blank?
conf.add_repo(repo, true) repo.add_permission("RW+", "", name_masters) unless name_masters.blank?
end
ga_repo.save repo
end end
end end
end end
...@@ -300,5 +300,8 @@ end ...@@ -300,5 +300,8 @@ end
# code :string(255) # code :string(255)
# owner_id :integer # owner_id :integer
# default_branch :string(255) default("master"), not null # 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
# #
# == 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment