summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--app/models/ci/project.rb2
-rw-r--r--app/models/project.rb1
-rw-r--r--app/views/ci/projects/edit.html.haml2
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml5
-rw-r--r--app/views/projects/_home_panel.html.haml4
-rw-r--r--config/gitlab.yml.example22
-rw-r--r--config/initializers/1_settings.rb1
-rw-r--r--db/migrate/20150916145038_add_index_for_committed_at_and_id.rb5
-rw-r--r--db/schema.rb3
-rw-r--r--doc/integration/ldap.md20
-rw-r--r--doc/markdown/markdown.md2
-rw-r--r--lib/ci/api/helpers.rb2
-rw-r--r--lib/ci/migrate/tags.rb2
-rw-r--r--lib/gitlab/ldap/auth_hash.rb35
-rw-r--r--lib/gitlab/ldap/config.rb4
-rw-r--r--lib/gitlab/ldap/user.rb4
-rw-r--r--lib/gitlab/o_auth/auth_hash.rb22
-rw-r--r--public/ci/build-skipped.svg1
-rw-r--r--spec/lib/gitlab/ldap/auth_hash_spec.rb65
-rw-r--r--spec/lib/gitlab/ldap/user_spec.rb2
-rw-r--r--spec/lib/gitlab/o_auth/auth_hash_spec.rb6
-rw-r--r--spec/lib/gitlab/o_auth/user_spec.rb2
-rw-r--r--spec/models/ci/project_spec.rb18
24 files changed, 209 insertions, 22 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 71238630d31..ee70789babc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,7 @@ v 7.14.3
v 7.14.2
- Upgrade gitlab_git to 7.2.15 to fix `git blame` errors with ISO-encoded files (Stan Hu)
+ - Allow configuration of LDAP attributes GitLab will use for the new user account.
v 7.14.1
- Improve abuse reports management from admin area
diff --git a/app/models/ci/project.rb b/app/models/ci/project.rb
index 2cf1783616f..ae901d4ccd0 100644
--- a/app/models/ci/project.rb
+++ b/app/models/ci/project.rb
@@ -33,7 +33,7 @@ module Ci
belongs_to :gl_project, class_name: '::Project', foreign_key: :gitlab_id
- has_many :commits, ->() { order(:committed_at) }, dependent: :destroy, class_name: 'Ci::Commit'
+ has_many :commits, ->() { order('CASE WHEN ci_commits.committed_at IS NULL THEN 0 ELSE 1 END', :committed_at, :id) }, dependent: :destroy, class_name: 'Ci::Commit'
has_many :builds, through: :commits, dependent: :destroy, class_name: 'Ci::Build'
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
has_many :runners, through: :runner_projects, class_name: 'Ci::Runner'
diff --git a/app/models/project.rb b/app/models/project.rb
index 81951467d41..6e2f9645661 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -119,6 +119,7 @@ class Project < ActiveRecord::Base
has_many :starrers, through: :users_star_projects, source: :user
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
+ has_one :gitlab_ci_project, dependent: :destroy, class_name: "Ci::Project", foreign_key: :gitlab_id
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
diff --git a/app/views/ci/projects/edit.html.haml b/app/views/ci/projects/edit.html.haml
index 298007a6565..79e8fd3a295 100644
--- a/app/views/ci/projects/edit.html.haml
+++ b/app/views/ci/projects/edit.html.haml
@@ -1,6 +1,6 @@
- if @project.generated_yaml_config
%p.alert.alert-danger
- CI Jobs are deprecated now, you can #{link_to "download", dumped_yaml_project_path(@project)}
+ CI Jobs are deprecated now, you can #{link_to "download", dumped_yaml_ci_project(@project)}
or
%a.preview-yml{:href => "#yaml-content", "data-toggle" => "modal"} preview
yaml file which is based on your old jobs.
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index c3b07200621..56283cba6bd 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -46,3 +46,8 @@
= icon('user fw')
%span
Profile Settings
+ = nav_link(controller: :ci) do
+ = link_to ci_root_path, title: 'Continuous Integration', data: {placement: 'right'} do
+ = icon('building fw')
+ %span
+ CI
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index dbecd1e7192..b347846c932 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -28,4 +28,8 @@
= render 'projects/buttons/dropdown'
+ - if @project.gitlab_ci?
+ = link_to ci_project_path(@project.gitlab_ci_project), class: 'btn btn-default' do
+ CI
+
= render "shared/clone_panel"
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index b2bd8796004..0005d44e0f2 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -159,7 +159,7 @@ production: &base
method: 'plain' # "tls" or "ssl" or "plain"
bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
password: '_the_password_of_the_bind_user'
-
+
# This setting specifies if LDAP server is Active Directory LDAP server.
# For non AD servers it skips the AD specific queries.
# If your LDAP server is not AD, set this to false.
@@ -196,6 +196,26 @@ production: &base
#
user_filter: ''
+ # LDAP attributes that GitLab will use to create an account for the LDAP user.
+ # The specified attribute can either be the attribute name as a string (e.g. 'mail'),
+ # or an array of attribute names to try in order (e.g. ['mail', 'email']).
+ # Note that the user's LDAP login will always be the attribute specified as `uid` above.
+ attributes:
+ # The username will be used in paths for the user's own projects
+ # (like `gitlab.example.com/username/project`) and when mentioning
+ # them in issues, merge request and comments (like `@username`).
+ # If the attribute specified for `username` contains an email address,
+ # the GitLab username will be the part of the email address before the '@'.
+ username: ['uid', 'userid', 'sAMAccountName']
+ email: ['mail', 'email', 'userPrincipalName']
+
+ # If no full name could be found at the attribute specified for `name`,
+ # the full name is determined using the attributes specified for
+ # `first_name` and `last_name`.
+ name: 'cn'
+ first_name: 'givenName'
+ last_name: 'sn'
+
# GitLab EE only: add more LDAP servers
# Choose an ID made of a-z and 0-9 . This ID will be stored in the database
# so that GitLab can remember which LDAP server a user belongs to.
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 339419559d1..fe81ffd4205 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -109,6 +109,7 @@ if Settings.ldap['enabled'] || Rails.env.test?
server['block_auto_created_users'] = false if server['block_auto_created_users'].nil?
server['allow_username_or_email_login'] = false if server['allow_username_or_email_login'].nil?
server['active_directory'] = true if server['active_directory'].nil?
+ server['attributes'] = {} if server['attributes'].nil?
server['provider_name'] ||= "ldap#{key}".downcase
server['provider_class'] = OmniAuth::Utils.camelize(server['provider_name'])
end
diff --git a/db/migrate/20150916145038_add_index_for_committed_at_and_id.rb b/db/migrate/20150916145038_add_index_for_committed_at_and_id.rb
new file mode 100644
index 00000000000..78d9e5f61a1
--- /dev/null
+++ b/db/migrate/20150916145038_add_index_for_committed_at_and_id.rb
@@ -0,0 +1,5 @@
+class AddIndexForCommittedAtAndId < ActiveRecord::Migration
+ def change
+ add_index :ci_commits, [:project_id, :committed_at, :id]
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5fd764bf698..48314b8db6a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150914215247) do
+ActiveRecord::Schema.define(version: 20150916145038) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -118,6 +118,7 @@ ActiveRecord::Schema.define(version: 20150914215247) do
t.datetime "committed_at"
end
+ add_index "ci_commits", ["project_id", "committed_at", "id"], name: "index_ci_commits_on_project_id_and_committed_at_and_id", using: :btree
add_index "ci_commits", ["project_id", "committed_at"], name: "index_ci_commits_on_project_id_and_committed_at", using: :btree
add_index "ci_commits", ["project_id", "sha"], name: "index_ci_commits_on_project_id_and_sha", using: :btree
add_index "ci_commits", ["project_id"], name: "index_ci_commits_on_project_id", using: :btree
diff --git a/doc/integration/ldap.md b/doc/integration/ldap.md
index 904d5d7fee2..3bc5df21ef4 100644
--- a/doc/integration/ldap.md
+++ b/doc/integration/ldap.md
@@ -78,6 +78,26 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server
#
user_filter: ''
+ # LDAP attributes that GitLab will use to create an account for the LDAP user.
+ # The specified attribute can either be the attribute name as a string (e.g. 'mail'),
+ # or an array of attribute names to try in order (e.g. ['mail', 'email']).
+ # Note that the user's LDAP login will always be the attribute specified as `uid` above.
+ attributes:
+ # The username will be used in paths for the user's own projects
+ # (like `gitlab.example.com/username/project`) and when mentioning
+ # them in issues, merge request and comments (like `@username`).
+ # If the attribute specified for `username` contains an email address,
+ # the GitLab username will be the part of the email address before the '@'.
+ username: ['uid', 'userid', 'sAMAccountName']
+ email: ['mail', 'email', 'userPrincipalName']
+
+ # If no full name could be found at the attribute specified for `name`,
+ # the full name is determined using the attributes specified for
+ # `first_name` and `last_name`.
+ name: 'cn'
+ first_name: 'givenName'
+ last_name: 'sn'
+
# GitLab EE only: add more LDAP servers
# Choose an ID made of a-z and 0-9 . This ID will be stored in the database
# so that GitLab can remember which LDAP server a user belongs to.
diff --git a/doc/markdown/markdown.md b/doc/markdown/markdown.md
index 322111ae9e1..6fdb2fe1491 100644
--- a/doc/markdown/markdown.md
+++ b/doc/markdown/markdown.md
@@ -413,7 +413,7 @@ Some text to show that the reference links can follow later.
Relative links do not allow referencing project files in a wiki page or wiki page in a project file. The reason for this is that, in GitLab, wiki is always a separate git repository. For example:
-`[I'm a reference-style link][style]`
+`[I'm a reference-style link](style)`
will point the link to `wikis/style` when the link is inside of a wiki markdown file.
diff --git a/lib/ci/api/helpers.rb b/lib/ci/api/helpers.rb
index 9197f917d73..e602cda81d6 100644
--- a/lib/ci/api/helpers.rb
+++ b/lib/ci/api/helpers.rb
@@ -1,6 +1,8 @@
module Ci
module API
module Helpers
+ UPDATE_RUNNER_EVERY = 60
+
def authenticate_runners!
forbidden! unless params[:token] == GitlabCi::REGISTRATION_TOKEN
end
diff --git a/lib/ci/migrate/tags.rb b/lib/ci/migrate/tags.rb
index f4114c698d2..125a535e9a9 100644
--- a/lib/ci/migrate/tags.rb
+++ b/lib/ci/migrate/tags.rb
@@ -40,7 +40,7 @@ module Ci
tags = ActiveRecord::Base.connection.select_all(
'select ci_tags.name from ci_tags ' +
'join ci_taggings on ci_tags.id = ci_taggings.tag_id ' +
- "where taggable_type = #{ActiveRecord::Base::sanitize(type)} and taggable_id = #{ActiveRecord::Base::sanitize(id)} and context = \"tags\""
+ "where taggable_type = #{ActiveRecord::Base::sanitize(type)} and taggable_id = #{ActiveRecord::Base::sanitize(id)} and context = 'tags'"
)
tags.map { |tag| tag['name'] }
end
diff --git a/lib/gitlab/ldap/auth_hash.rb b/lib/gitlab/ldap/auth_hash.rb
new file mode 100644
index 00000000000..55deeeacd90
--- /dev/null
+++ b/lib/gitlab/ldap/auth_hash.rb
@@ -0,0 +1,35 @@
+# Class to parse and transform the info provided by omniauth
+#
+module Gitlab
+ module LDAP
+ class AuthHash < Gitlab::OAuth::AuthHash
+ private
+
+ def get_info(key)
+ attributes = ldap_config.attributes[key]
+ return super unless attributes
+
+ attributes = Array(attributes)
+
+ value = nil
+ attributes.each do |attribute|
+ value = get_raw(attribute)
+ break if value.present?
+ end
+
+ return super unless value
+
+ Gitlab::Utils.force_utf8(value)
+ value
+ end
+
+ def get_raw(key)
+ auth_hash.extra[:raw_info][key]
+ end
+
+ def ldap_config
+ @ldap_config ||= Gitlab::LDAP::Config.new(self.provider)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb
index d2ffa2e1fe8..101a3285f4b 100644
--- a/lib/gitlab/ldap/config.rb
+++ b/lib/gitlab/ldap/config.rb
@@ -84,6 +84,10 @@ module Gitlab
options['block_auto_created_users']
end
+ def attributes
+ options['attributes']
+ end
+
protected
def base_config
Gitlab.config.ldap
diff --git a/lib/gitlab/ldap/user.rb b/lib/gitlab/ldap/user.rb
index 04a22237478..cb66fd500fe 100644
--- a/lib/gitlab/ldap/user.rb
+++ b/lib/gitlab/ldap/user.rb
@@ -71,6 +71,10 @@ module Gitlab
def ldap_config
Gitlab::LDAP::Config.new(auth_hash.provider)
end
+
+ def auth_hash=(auth_hash)
+ @auth_hash = Gitlab::LDAP::AuthHash.new(auth_hash)
+ end
end
end
end
diff --git a/lib/gitlab/o_auth/auth_hash.rb b/lib/gitlab/o_auth/auth_hash.rb
index 9b8e783d16c..d94b104bbf8 100644
--- a/lib/gitlab/o_auth/auth_hash.rb
+++ b/lib/gitlab/o_auth/auth_hash.rb
@@ -16,16 +16,6 @@ module Gitlab
@provider ||= Gitlab::Utils.force_utf8(auth_hash.provider.to_s)
end
- def info
- auth_hash.info
- end
-
- def get_info(key)
- value = info.try(key)
- Gitlab::Utils.force_utf8(value) if value
- value
- end
-
def name
@name ||= get_info(:name) || "#{get_info(:first_name)} #{get_info(:last_name)}"
end
@@ -44,9 +34,19 @@ module Gitlab
private
+ def info
+ auth_hash.info
+ end
+
+ def get_info(key)
+ value = info[key]
+ Gitlab::Utils.force_utf8(value) if value
+ value
+ end
+
def username_and_email
@username_and_email ||= begin
- username = get_info(:nickname) || get_info(:username)
+ username = get_info(:username) || get_info(:nickname)
email = get_info(:email)
username ||= generate_username(email) if email
diff --git a/public/ci/build-skipped.svg b/public/ci/build-skipped.svg
new file mode 100644
index 00000000000..f15507188e0
--- /dev/null
+++ b/public/ci/build-skipped.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="97" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="97" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h37v20H0z"/><path fill="#9f9f9f" d="M37 0h60v20H37z"/><path fill="url(#b)" d="M0 0h97v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="18.5" y="15" fill="#010101" fill-opacity=".3">build</text><text x="18.5" y="14">build</text><text x="66" y="15" fill="#010101" fill-opacity=".3">skipped</text><text x="66" y="14">skipped</text></g></svg> \ No newline at end of file
diff --git a/spec/lib/gitlab/ldap/auth_hash_spec.rb b/spec/lib/gitlab/ldap/auth_hash_spec.rb
new file mode 100644
index 00000000000..18c7924fea1
--- /dev/null
+++ b/spec/lib/gitlab/ldap/auth_hash_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+
+describe Gitlab::LDAP::AuthHash do
+ let(:auth_hash) do
+ Gitlab::LDAP::AuthHash.new(
+ OmniAuth::AuthHash.new(
+ uid: '123456',
+ provider: 'ldapmain',
+ info: info,
+ extra: {
+ raw_info: raw_info
+ }
+ )
+ )
+ end
+
+ let(:info) do
+ {
+ name: 'Smith, J.',
+ email: 'johnsmith@example.com',
+ nickname: '123456'
+ }
+ end
+
+ let(:raw_info) do
+ {
+ uid: '123456',
+ email: 'johnsmith@example.com',
+ cn: 'Smith, J.',
+ fullName: 'John Smith'
+ }
+ end
+
+ context "without overridden attributes" do
+
+ it "has the correct username" do
+ expect(auth_hash.username).to eq("123456")
+ end
+
+ it "has the correct name" do
+ expect(auth_hash.name).to eq("Smith, J.")
+ end
+ end
+
+ context "with overridden attributes" do
+ let(:attributes) do
+ {
+ username: ['mail', 'email'],
+ name: 'fullName'
+ }
+ end
+
+ before do
+ allow_any_instance_of(Gitlab::LDAP::Config).to receive(:attributes).and_return(attributes)
+ end
+
+ it "has the correct username" do
+ expect(auth_hash.username).to eq("johnsmith@example.com")
+ end
+
+ it "has the correct name" do
+ expect(auth_hash.name).to eq("John Smith")
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index 84d9fb54b61..fd2e5f6d0e1 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -11,7 +11,7 @@ describe Gitlab::LDAP::User do
}
end
let(:auth_hash) do
- double(uid: 'my-uid', provider: 'ldapmain', info: double(info))
+ OmniAuth::AuthHash.new(uid: 'my-uid', provider: 'ldapmain', info: info)
end
describe :changed? do
diff --git a/spec/lib/gitlab/o_auth/auth_hash_spec.rb b/spec/lib/gitlab/o_auth/auth_hash_spec.rb
index e4a6cd954cc..5632f2306ec 100644
--- a/spec/lib/gitlab/o_auth/auth_hash_spec.rb
+++ b/spec/lib/gitlab/o_auth/auth_hash_spec.rb
@@ -3,11 +3,11 @@ require 'spec_helper'
describe Gitlab::OAuth::AuthHash do
let(:auth_hash) do
Gitlab::OAuth::AuthHash.new(
- double({
+ OmniAuth::AuthHash.new(
provider: provider_ascii,
uid: uid_ascii,
- info: double(info_hash)
- })
+ info: info_hash
+ )
)
end
diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb
index c6cca98a037..c0083fc85be 100644
--- a/spec/lib/gitlab/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/o_auth/user_spec.rb
@@ -5,7 +5,7 @@ describe Gitlab::OAuth::User do
let(:gl_user) { oauth_user.gl_user }
let(:uid) { 'my-uid' }
let(:provider) { 'my-provider' }
- let(:auth_hash) { double(uid: uid, provider: provider, info: double(info_hash)) }
+ let(:auth_hash) { OmniAuth::AuthHash.new(uid: uid, provider: provider, info: info_hash) }
let(:info_hash) do
{
nickname: '-john+gitlab-ETC%.git@gmail.com',
diff --git a/spec/models/ci/project_spec.rb b/spec/models/ci/project_spec.rb
index 1025868da6e..261ea69f5b4 100644
--- a/spec/models/ci/project_spec.rb
+++ b/spec/models/ci/project_spec.rb
@@ -61,6 +61,24 @@ describe Ci::Project do
end
end
+ describe 'ordered commits' do
+ let(:project) { FactoryGirl.create :ci_project }
+
+ it 'returns ordered list of commits' do
+ commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, project: project
+ commit2 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, project: project
+ expect(project.commits).to eq([commit2, commit1])
+ end
+
+ it 'returns commits ordered by committed_at and id, with nulls last' do
+ commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, project: project
+ commit2 = FactoryGirl.create :ci_commit, committed_at: nil, project: project
+ commit3 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, project: project
+ commit4 = FactoryGirl.create :ci_commit, committed_at: nil, project: project
+ expect(project.commits).to eq([commit2, commit4, commit3, commit1])
+ end
+ end
+
context :valid_project do
let(:project) { FactoryGirl.create :ci_project }