diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/models/ci/project.rb | 2 | ||||
-rw-r--r-- | app/models/project.rb | 1 | ||||
-rw-r--r-- | app/views/ci/projects/edit.html.haml | 2 | ||||
-rw-r--r-- | app/views/layouts/nav/_dashboard.html.haml | 5 | ||||
-rw-r--r-- | app/views/projects/_home_panel.html.haml | 4 | ||||
-rw-r--r-- | config/gitlab.yml.example | 22 | ||||
-rw-r--r-- | config/initializers/1_settings.rb | 1 | ||||
-rw-r--r-- | db/migrate/20150916145038_add_index_for_committed_at_and_id.rb | 5 | ||||
-rw-r--r-- | db/schema.rb | 3 | ||||
-rw-r--r-- | doc/integration/ldap.md | 20 | ||||
-rw-r--r-- | doc/markdown/markdown.md | 2 | ||||
-rw-r--r-- | lib/ci/api/helpers.rb | 2 | ||||
-rw-r--r-- | lib/ci/migrate/tags.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/ldap/auth_hash.rb | 35 | ||||
-rw-r--r-- | lib/gitlab/ldap/config.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/ldap/user.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/o_auth/auth_hash.rb | 22 | ||||
-rw-r--r-- | public/ci/build-skipped.svg | 1 | ||||
-rw-r--r-- | spec/lib/gitlab/ldap/auth_hash_spec.rb | 65 | ||||
-rw-r--r-- | spec/lib/gitlab/ldap/user_spec.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/o_auth/auth_hash_spec.rb | 6 | ||||
-rw-r--r-- | spec/lib/gitlab/o_auth/user_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/ci/project_spec.rb | 18 |
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 } |