Commit 4d7b895c authored by Marin Jankovski's avatar Marin Jankovski

Merge branch 'master' into git_hook_api

parents aee56737 da86eace
v 7.5.0
- Added an ability to check each author commit's email by regex
- Added an abulity to restrict commit authors to existing Gitlab users
- Add an option for automatic daily LDAP user sync
v 7.4.0 v 7.4.0
- Support for multiple LDAP servers - Support for multiple LDAP servers
- Skip AD specific LDAP checks - Skip AD specific LDAP checks
......
...@@ -114,6 +114,7 @@ gem "acts-as-taggable-on" ...@@ -114,6 +114,7 @@ gem "acts-as-taggable-on"
gem 'slim' gem 'slim'
gem 'sinatra', require: nil gem 'sinatra', require: nil
gem 'sidekiq', '2.17.0' gem 'sidekiq', '2.17.0'
gem 'sidetiq', '0.6.1'
# HTTP requests # HTTP requests
gem "httparty" gem "httparty"
......
...@@ -252,6 +252,7 @@ GEM ...@@ -252,6 +252,7 @@ GEM
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
httpauth (0.2.1) httpauth (0.2.1)
i18n (0.6.11) i18n (0.6.11)
ice_cube (0.12.1)
ice_nine (0.10.0) ice_nine (0.10.0)
jasmine (2.0.2) jasmine (2.0.2)
jasmine-core (~> 2.0.0) jasmine-core (~> 2.0.0)
...@@ -477,6 +478,10 @@ GEM ...@@ -477,6 +478,10 @@ GEM
json json
redis (>= 3.0.4) redis (>= 3.0.4)
redis-namespace (>= 1.3.1) redis-namespace (>= 1.3.1)
sidetiq (0.6.1)
celluloid (>= 0.14.1)
ice_cube (~> 0.12.0)
sidekiq (>= 2.16.0)
simple_oauth (0.1.9) simple_oauth (0.1.9)
simplecov (0.9.0) simplecov (0.9.0)
docile (~> 1.1.0) docile (~> 1.1.0)
...@@ -686,6 +691,7 @@ DEPENDENCIES ...@@ -686,6 +691,7 @@ DEPENDENCIES
settingslogic settingslogic
shoulda-matchers (~> 2.1.0) shoulda-matchers (~> 2.1.0)
sidekiq (= 2.17.0) sidekiq (= 2.17.0)
sidetiq (= 0.6.1)
simplecov simplecov
sinatra sinatra
six six
......
...@@ -27,6 +27,7 @@ class Projects::GitHooksController < Projects::ApplicationController ...@@ -27,6 +27,7 @@ class Projects::GitHooksController < Projects::ApplicationController
# Only allow a trusted parameter "white list" through. # Only allow a trusted parameter "white list" through.
def git_hook_params def git_hook_params
params.require(:git_hook).permit(:deny_delete_tag, :delete_branch_regex, :commit_message_regex, :force_push_regex) params.require(:git_hook).permit(:deny_delete_tag, :delete_branch_regex,
:commit_message_regex, :force_push_regex, :author_email_regex, :member_check)
end end
end end
...@@ -13,4 +13,8 @@ class GitHook < ActiveRecord::Base ...@@ -13,4 +13,8 @@ class GitHook < ActiveRecord::Base
true true
end end
end end
def commit_validation?
commit_message_regex.present? || author_email_regex.present? || member_check
end
end end
...@@ -213,6 +213,10 @@ class User < ActiveRecord::Base ...@@ -213,6 +213,10 @@ class User < ActiveRecord::Base
User.where(name: name).first User.where(name: name).first
end end
def existing_member?(email)
User.where(email: email).any? || Email.where(email: email).any?
end
def filter(filter_name) def filter(filter_name)
case filter_name case filter_name
when "admins"; self.admins when "admins"; self.admins
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
.form-group .form-group
= f.label :deny_delete_tag, "Prevent tag removal", class: 'control-label' = f.label :deny_delete_tag, "Prevent tag removal", class: 'control-label'
.col-sm-10 .col-sm-10
%label
.checkbox .checkbox
= f.check_box :deny_delete_tag = f.check_box :deny_delete_tag
%span.descr %span.descr
...@@ -21,6 +22,15 @@ ...@@ -21,6 +22,15 @@
%code git push %code git push
Tags can still be deleted through the web UI. Tags can still be deleted through the web UI.
.form-group
= f.label :member_check, "Restrict commit authors to existing Gitlab users", class: 'control-label'
.col-sm-10
%label
.checkbox
= f.check_box :member_check
%span.descr
Check whether author is a GitLab member
-#.form-group -#.form-group
= f.label :force_push_regex, "Force push", class: 'control-label' = f.label :force_push_regex, "Force push", class: 'control-label'
.col-sm-10 .col-sm-10
...@@ -44,5 +54,15 @@ ...@@ -44,5 +54,15 @@
If this field is empty it allows any commit message. If this field is empty it allows any commit message.
For example you can require that an issue number is always mentioned in the commit message. For example you can require that an issue number is always mentioned in the commit message.
.form-group
= f.label :author_email_regex, "Commit author's email", class: 'control-label'
.col-sm-10
= f.text_field :author_email_regex, class: "form-control", placeholder: 'Example: Fixes @my-company.com$'
%p.hint
All commit author's email must match this
= link_to 'Ruby regular expression', 'http://www.ruby-doc.org/core-2.1.1/Regexp.html'
to be pushed.
If this field is empty it allows any email.
.form-actions .form-actions
= f.submit "Save Git hooks", class: "btn btn-create" = f.submit "Save Git hooks", class: "btn btn-create"
class LdapSyncWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
if Gitlab.config.ldap.enabled
HOUR = Gitlab.config.ldap.schedule_sync_hour
MINUTE = Gitlab.config.ldap.schedule_sync_minute
recurrence { daily.hour_of_day(HOUR).minute_of_hour(MINUTE) }
end
def perform
Rails.logger.info "Performing daily LDAP sync task."
User.ldap.find_each(batch_size: 100).each do |ldap_user|
Rails.logger.debug "Syncing user #{ldap_user.username}, #{ldap_user.email}"
Gitlab::LDAP::Access.allowed?(ldap_user)
end
end
end
...@@ -135,6 +135,14 @@ production: &base ...@@ -135,6 +135,14 @@ production: &base
# bundle exec rake gitlab:ldap:check RAILS_ENV=production # bundle exec rake gitlab:ldap:check RAILS_ENV=production
ldap: ldap:
enabled: false enabled: false
# GitLab EE only.
# In addition to refreshing users when they log in,
# enabling this setting will refresh LDAP user membership once a day.
# Default time of the day when this will happen is at 1:30am server time.
schedule_sync_hour: 1 # Hour of the day. Value from 0-23.
schedule_sync_minute: 30 # Minute of the hour. Value from 0-59.
servers: servers:
main: # 'main' is the GitLab 'provider ID' of this LDAP server main: # 'main' is the GitLab 'provider ID' of this LDAP server
## label ## label
......
...@@ -56,6 +56,8 @@ end ...@@ -56,6 +56,8 @@ end
Settings['ldap'] ||= Settingslogic.new({}) Settings['ldap'] ||= Settingslogic.new({})
Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil? Settings.ldap['enabled'] = false if Settings.ldap['enabled'].nil?
Settings.ldap['sync_time'] = 3600 if Settings.ldap['sync_time'].nil? Settings.ldap['sync_time'] = 3600 if Settings.ldap['sync_time'].nil?
Settings.ldap['schedule_sync_hour'] = 1 if Settings.ldap['schedule_sync_hour'].nil?
Settings.ldap['schedule_sync_minute'] = 30 if Settings.ldap['schedule_sync_minute'].nil?
# backwards compatibility, we only have one host # backwards compatibility, we only have one host
if Settings.ldap['enabled'] || Rails.env.test? if Settings.ldap['enabled'] || Rails.env.test?
......
class AddAuthorEmailRegexToGitHook < ActiveRecord::Migration
def change
add_column :git_hooks, :author_email_regex, :string
end
end
class AddMemberCheckToGitHooks < ActiveRecord::Migration
def change
add_column :git_hooks, :member_check, :boolean, default: false, null: false
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20141010132608) do ActiveRecord::Schema.define(version: 20141030133853) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
...@@ -91,6 +91,8 @@ ActiveRecord::Schema.define(version: 20141010132608) do ...@@ -91,6 +91,8 @@ ActiveRecord::Schema.define(version: 20141010132608) do
t.integer "project_id" t.integer "project_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "author_email_regex"
t.boolean "member_check", default: false, null: false
end end
create_table "issues", force: true do |t| create_table "issues", force: true do |t|
......
Feature: Git Hooks
Background:
Given I sign in as a user
And I own project "Shop"
Scenario: I should see git hook form
When I visit project git hooks page
Then I should see git hook form
\ No newline at end of file
require 'webmock'
class Spinach::Features::GitHooks < Spinach::FeatureSteps
include SharedAuthentication
include SharedProject
include SharedPaths
include RSpec::Matchers
include RSpec::Mocks::ExampleMethods
include WebMock::API
step 'I should see git hook form' do
page.should have_selector('input#git_hook_commit_message_regex')
page.should have_content "Commit message"
page.should have_content "Commit author's email"
end
end
...@@ -228,6 +228,10 @@ module SharedPaths ...@@ -228,6 +228,10 @@ module SharedPaths
visit project_hooks_path(@project) visit project_hooks_path(@project)
end end
step 'I visit project git hooks page' do
visit project_git_hooks_path(@project)
end
step 'I visit project deploy keys page' do step 'I visit project deploy keys page' do
visit project_deploy_keys_path(@project) visit project_deploy_keys_path(@project)
end end
......
...@@ -109,11 +109,24 @@ module Gitlab ...@@ -109,11 +109,24 @@ module Gitlab
end end
# Check commit messages unless its branch removal # Check commit messages unless its branch removal
if git_hook.commit_message_regex.present? && newrev !~ /00000000/ if git_hook.commit_validation? && newrev !~ /00000000/
commits = project.repository.commits_between(oldrev, newrev) commits = project.repository.commits_between(oldrev, newrev)
commits.each do |commit| commits.each do |commit|
unless commit.safe_message =~ Regexp.new(git_hook.commit_message_regex) if git_hook.commit_message_regex.present?
return false return false unless commit.safe_message =~ Regexp.new(git_hook.commit_message_regex)
end
if git_hook.author_email_regex.present?
return false unless commit.committer_email =~ Regexp.new(git_hook.author_email_regex)
return false unless commit.author_email =~ Regexp.new(git_hook.author_email_regex)
end
# Check whether author is a GitLab member
if git_hook.member_check
return false unless User.existing_member?(commit.author_email)
if commit.author_email != commit.committer_email
return false unless User.existing_member?(commit.committer_email)
end
end end
end end
end end
...@@ -144,5 +157,6 @@ module Gitlab ...@@ -144,5 +157,6 @@ module Gitlab
nil nil
end end
end end
end end
end end
...@@ -449,6 +449,27 @@ describe User do ...@@ -449,6 +449,27 @@ describe User do
end end
end end
describe "#existing_member?" do
it "returns true for exisitng user" do
create :user, email: "bruno@example.com"
expect(User.existing_member?("bruno@example.com")).to be_true
end
it "returns false for unknown exisitng user" do
create :user, email: "bruno@example.com"
expect(User.existing_member?("rendom@example.com")).to be_false
end
it "returns true if additional email exists" do
user = create :user
user.emails.create(email: "bruno@example.com")
expect(User.existing_member?("bruno@example.com")).to be_true
end
end
describe "#sort" do describe "#sort" do
before do before do
User.delete_all User.delete_all
......
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