diff options
Diffstat (limited to 'lib/gitlab')
26 files changed, 454 insertions, 131 deletions
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 30509528b8b..076e2af7d38 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -1,17 +1,86 @@ module Gitlab - class Auth - def find(login, password) - user = User.by_login(login) - - # If no user is found, or it's an LDAP server, try LDAP. - # LDAP users are only authenticated via LDAP - if user.nil? || user.ldap_user? - # Second chance - try LDAP authentication - return nil unless Gitlab::LDAP::Config.enabled? - - Gitlab::LDAP::Authentication.login(login, password) - else - user if user.valid_password?(password) + module Auth + Result = Struct.new(:user, :type) + + class << self + def find(login, password, project:, ip:) + raise "Must provide an IP for rate limiting" if ip.nil? + + result = Result.new + + if valid_ci_request?(login, password, project) + result.type = :ci + elsif result.user = find_in_gitlab_or_ldap(login, password) + result.type = :gitlab_or_ldap + elsif result.user = oauth_access_token_check(login, password) + result.type = :oauth + end + + rate_limit!(ip, success: !!result.user || (result.type == :ci), login: login) + result + end + + def find_in_gitlab_or_ldap(login, password) + user = User.by_login(login) + + # If no user is found, or it's an LDAP server, try LDAP. + # LDAP users are only authenticated via LDAP + if user.nil? || user.ldap_user? + # Second chance - try LDAP authentication + return nil unless Gitlab::LDAP::Config.enabled? + + Gitlab::LDAP::Authentication.login(login, password) + else + user if user.valid_password?(password) + end + end + + def rate_limit!(ip, success:, login:) + rate_limiter = Gitlab::Auth::IpRateLimiter.new(ip) + return unless rate_limiter.enabled? + + if success + # Repeated login 'failures' are normal behavior for some Git clients so + # it is important to reset the ban counter once the client has proven + # they are not a 'bad guy'. + rate_limiter.reset! + else + # Register a login failure so that Rack::Attack can block the next + # request from this IP if needed. + rate_limiter.register_fail! + + if rate_limiter.banned? + Rails.logger.info "IP #{ip} failed to login " \ + "as #{login} but has been temporarily banned from Git auth" + end + end + end + + private + + def valid_ci_request?(login, password, project) + matched_login = /(?<service>^[a-zA-Z]*-ci)-token$/.match(login) + + return false unless project && matched_login.present? + + underscored_service = matched_login['service'].underscore + + if underscored_service == 'gitlab_ci' + project && project.valid_build_token?(password) + elsif Service.available_services_names.include?(underscored_service) + # We treat underscored_service as a trusted input because it is included + # in the Service.available_services_names whitelist. + service = project.public_send("#{underscored_service}_service") + + service && service.activated? && service.valid_token?(password) + end + end + + def oauth_access_token_check(login, password) + if login == "oauth2" && password.present? + token = Doorkeeper::AccessToken.by_token(password) + token && token.accessible? && User.find_by(id: token.resource_owner_id) + end end end end diff --git a/lib/gitlab/auth/ip_rate_limiter.rb b/lib/gitlab/auth/ip_rate_limiter.rb new file mode 100644 index 00000000000..1089bc9f89e --- /dev/null +++ b/lib/gitlab/auth/ip_rate_limiter.rb @@ -0,0 +1,42 @@ +module Gitlab + module Auth + class IpRateLimiter + attr_reader :ip + + def initialize(ip) + @ip = ip + @banned = false + end + + def enabled? + config.enabled + end + + def reset! + Rack::Attack::Allow2Ban.reset(ip, config) + end + + def register_fail! + # Allow2Ban.filter will return false if this IP has not failed too often yet + @banned = Rack::Attack::Allow2Ban.filter(ip, config) do + # If we return false here, the failure for this IP is ignored by Allow2Ban + ip_can_be_banned? + end + end + + def banned? + @banned + end + + private + + def config + Gitlab.config.rack_attack.git_basic_auth + end + + def ip_can_be_banned? + config.ip_whitelist.exclude?(ip) + end + end + end +end diff --git a/lib/gitlab/award_emoji.rb b/lib/gitlab/award_emoji.rb new file mode 100644 index 00000000000..51b1df9ecbd --- /dev/null +++ b/lib/gitlab/award_emoji.rb @@ -0,0 +1,84 @@ +module Gitlab + class AwardEmoji + CATEGORIES = { + other: "Other", + objects: "Objects", + places: "Places", + travel_places: "Travel", + emoticons: "Emoticons", + objects_symbols: "Symbols", + nature: "Nature", + celebration: "Celebration", + people: "People", + activity: "Activity", + flags: "Flags", + food_drink: "Food" + }.with_indifferent_access + + CATEGORY_ALIASES = { + symbols: "objects_symbols", + foods: "food_drink", + travel: "travel_places" + }.with_indifferent_access + + def self.normalize_emoji_name(name) + aliases[name] || name + end + + def self.emoji_by_category + unless @emoji_by_category + @emoji_by_category = Hash.new { |h, key| h[key] = [] } + + emojis.each do |emoji_name, data| + data["name"] = emoji_name + + # Skip Fitzpatrick(tone) modifiers + next if data["category"] == "modifier" + + category = CATEGORY_ALIASES[data["category"]] || data["category"] + + @emoji_by_category[category] << data + end + + @emoji_by_category = @emoji_by_category.sort.to_h + end + + @emoji_by_category + end + + def self.emojis + @emojis ||= + begin + json_path = File.join(Rails.root, 'fixtures', 'emojis', 'index.json' ) + JSON.parse(File.read(json_path)) + end + end + + def self.aliases + @aliases ||= + begin + json_path = File.join(Rails.root, 'fixtures', 'emojis', 'aliases.json' ) + JSON.parse(File.read(json_path)) + end + end + + # Returns an Array of Emoji names and their asset URLs. + def self.urls + @urls ||= begin + path = File.join(Rails.root, 'fixtures', 'emojis', 'digests.json') + prefix = Gitlab::Application.config.assets.prefix + digest = Gitlab::Application.config.assets.digest + + JSON.parse(File.read(path)).map do |hash| + if digest + fname = "#{hash['unicode']}-#{hash['digest']}" + else + fname = hash['unicode'] + end + + { name: hash['name'], path: "#{prefix}/#{fname}.png" } + end + end + end + end +end diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index baa81d92dd9..f07ff1daf55 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -36,10 +36,7 @@ module Grack lfs_response = Gitlab::Lfs::Router.new(project, @user, @ci, @request).try_call return lfs_response unless lfs_response.nil? - if project && authorized_request? - # Tell gitlab-workhorse the request is OK, and what the GL_ID is - render_grack_auth_ok - elsif @user.nil? && !@ci + if @user.nil? && !@ci unauthorized else render_not_found @@ -98,7 +95,7 @@ module Grack end def authenticate_user(login, password) - user = Gitlab::Auth.new.find(login, password) + user = Gitlab::Auth.find_in_gitlab_or_ldap(login, password) unless user user = oauth_access_token_check(login, password) @@ -141,36 +138,6 @@ module Grack user end - def authorized_request? - return true if @ci - - case git_cmd - when *Gitlab::GitAccess::DOWNLOAD_COMMANDS - if !Gitlab.config.gitlab_shell.upload_pack - false - elsif user - Gitlab::GitAccess.new(user, project).download_access_check.allowed? - elsif project.public? - # Allow clone/fetch for public projects - true - else - false - end - when *Gitlab::GitAccess::PUSH_COMMANDS - if !Gitlab.config.gitlab_shell.receive_pack - false - elsif user - # Skip user authorization on upload request. - # It will be done by the pre-receive hook in the repository. - true - else - false - end - else - false - end - end - def git_cmd if @request.get? @request.params['service'] @@ -197,24 +164,6 @@ module Grack end end - def render_grack_auth_ok - repo_path = - if @request.path_info =~ /^([\w\.\/-]+)\.wiki\.git/ - ProjectWiki.new(project).repository.path_to_repo - else - project.repository.path_to_repo - end - - [ - 200, - { "Content-Type" => "application/json" }, - [JSON.dump({ - 'GL_ID' => Gitlab::ShellEnv.gl_id(@user), - 'RepoPath' => repo_path, - })] - ] - end - def render_not_found [404, { "Content-Type" => "text/plain" }, ["Not Found"]] end diff --git a/lib/gitlab/build_data_builder.rb b/lib/gitlab/build_data_builder.rb index 34e949130da..9f45aefda0f 100644 --- a/lib/gitlab/build_data_builder.rb +++ b/lib/gitlab/build_data_builder.rb @@ -3,7 +3,7 @@ module Gitlab class << self def build(build) project = build.project - commit = build.commit + commit = build.pipeline user = build.user data = { diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb new file mode 100644 index 00000000000..ffe633d4b63 --- /dev/null +++ b/lib/gitlab/ci/config.rb @@ -0,0 +1,16 @@ +module Gitlab + module Ci + class Config + class LoaderError < StandardError; end + + def initialize(config) + loader = Loader.new(config) + @config = loader.load! + end + + def to_hash + @config + end + end + end +end diff --git a/lib/gitlab/ci/config/loader.rb b/lib/gitlab/ci/config/loader.rb new file mode 100644 index 00000000000..dbf6eb0edbe --- /dev/null +++ b/lib/gitlab/ci/config/loader.rb @@ -0,0 +1,25 @@ +module Gitlab + module Ci + class Config + class Loader + class FormatError < StandardError; end + + def initialize(config) + @config = YAML.safe_load(config, [Symbol], [], true) + end + + def valid? + @config.is_a?(Hash) + end + + def load! + unless valid? + raise FormatError, 'Invalid configuration format' + end + + @config.deep_symbolize_keys + end + end + end + end +end diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 92c7e8b9d88..5e7532f57ae 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -26,7 +26,10 @@ module Gitlab signup_enabled: Settings.gitlab['signup_enabled'], signin_enabled: Settings.gitlab['signin_enabled'], gravatar_enabled: Settings.gravatar['enabled'], - sign_in_text: Settings.extra['sign_in_text'], + sign_in_text: nil, + after_sign_up_text: nil, + help_page_text: nil, + shared_runners_text: nil, restricted_visibility_levels: Settings.gitlab['restricted_visibility_levels'], max_attachment_size: Settings.gitlab['max_attachment_size'], session_expire_delay: Settings.gitlab['session_expire_delay'], diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb index 42bec913a45..04fa6a3a5de 100644 --- a/lib/gitlab/database.rb +++ b/lib/gitlab/database.rb @@ -16,6 +16,20 @@ module Gitlab database_version.match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1] end + def self.nulls_last_order(field, direction = 'ASC') + order = "#{field} #{direction}" + + if Gitlab::Database.postgresql? + order << ' NULLS LAST' + else + # `field IS NULL` will be `0` for non-NULL columns and `1` for NULL + # columns. In the (default) ascending order, `0` comes first. + order.prepend("#{field} IS NULL, ") if direction == 'ASC' + end + + order + end + def true_value if Gitlab::Database.postgresql? "'t'" diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index fd14234c558..978c3f7896d 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -11,7 +11,7 @@ module Gitlab # add_concurrent_index :users, :some_column # # See Rails' `add_index` for more info on the available arguments. - def add_concurrent_index(*args) + def add_concurrent_index(table_name, column_name, options = {}) if transaction_open? raise 'add_concurrent_index can not be run inside a transaction, ' \ 'you can disable transactions by calling disable_ddl_transaction! ' \ @@ -19,10 +19,10 @@ module Gitlab end if Database.postgresql? - args << { algorithm: :concurrently } + options = options.merge({ algorithm: :concurrently }) end - add_index(*args) + add_index(table_name, column_name, options) end # Updates the value of a column in batches. diff --git a/lib/gitlab/github_import/base_formatter.rb b/lib/gitlab/github_import/base_formatter.rb index 202263c6742..72992baffd4 100644 --- a/lib/gitlab/github_import/base_formatter.rb +++ b/lib/gitlab/github_import/base_formatter.rb @@ -9,6 +9,10 @@ module Gitlab @formatter = Gitlab::ImportFormatter.new end + def create! + self.klass.create!(self.attributes) + end + private def gl_user_id(github_id) diff --git a/lib/gitlab/github_import/client.rb b/lib/gitlab/github_import/client.rb index 67988ea3460..d325eca6d99 100644 --- a/lib/gitlab/github_import/client.rb +++ b/lib/gitlab/github_import/client.rb @@ -1,6 +1,9 @@ module Gitlab module GithubImport class Client + GITHUB_SAFE_REMAINING_REQUESTS = 100 + GITHUB_SAFE_SLEEP_TIME = 500 + attr_reader :client, :api def initialize(access_token) @@ -11,7 +14,7 @@ module Gitlab ) if access_token - ::Octokit.auto_paginate = true + ::Octokit.auto_paginate = false @api = ::Octokit::Client.new( access_token: access_token, @@ -36,7 +39,7 @@ module Gitlab def method_missing(method, *args, &block) if api.respond_to?(method) - api.send(method, *args, &block) + request { api.send(method, *args, &block) } else super(method, *args, &block) end @@ -55,6 +58,34 @@ module Gitlab def github_options config["args"]["client_options"].deep_symbolize_keys end + + def rate_limit + api.rate_limit! + end + + def rate_limit_exceed? + rate_limit.remaining <= GITHUB_SAFE_REMAINING_REQUESTS + end + + def rate_limit_sleep_time + rate_limit.resets_in + GITHUB_SAFE_SLEEP_TIME + end + + def request + sleep rate_limit_sleep_time if rate_limit_exceed? + + data = yield + + last_response = api.last_response + + while last_response.rels[:next] + sleep rate_limit_sleep_time if rate_limit_exceed? + last_response = last_response.rels[:next].get + data.concat(last_response.data) if last_response.data.is_a?(Array) + end + + data + end end end end diff --git a/lib/gitlab/github_import/comment_formatter.rb b/lib/gitlab/github_import/comment_formatter.rb index 7d679eaec6a..2c1b94ef2cd 100644 --- a/lib/gitlab/github_import/comment_formatter.rb +++ b/lib/gitlab/github_import/comment_formatter.rb @@ -8,6 +8,7 @@ module Gitlab commit_id: raw_data.commit_id, line_code: line_code, author_id: author_id, + type: type, created_at: raw_data.created_at, updated_at: raw_data.updated_at } @@ -53,6 +54,10 @@ module Gitlab def note formatter.author_line(author) + body end + + def type + 'LegacyDiffNote' if on_diff? + end end end end diff --git a/lib/gitlab/github_import/hook_formatter.rb b/lib/gitlab/github_import/hook_formatter.rb new file mode 100644 index 00000000000..db1fabaa18a --- /dev/null +++ b/lib/gitlab/github_import/hook_formatter.rb @@ -0,0 +1,23 @@ +module Gitlab + module GithubImport + class HookFormatter + EVENTS = %w[* create delete pull_request push].freeze + + attr_reader :raw + + delegate :id, :name, :active, to: :raw + + def initialize(raw) + @raw = raw + end + + def config + raw.config.attrs + end + + def valid? + (EVENTS & raw.events).any? && active + end + end + end +end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index 408d9b79632..e5cf66a0371 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -30,9 +30,8 @@ module Gitlab end def import_labels - client.labels(repo).each do |raw_data| - Label.create!(LabelFormatter.new(project, raw_data).attributes) - end + labels = client.labels(repo, per_page: 100) + labels.each { |raw| LabelFormatter.new(project, raw).create! } true rescue ActiveRecord::RecordInvalid => e @@ -40,9 +39,8 @@ module Gitlab end def import_milestones - client.list_milestones(repo, state: :all).each do |raw_data| - Milestone.create!(MilestoneFormatter.new(project, raw_data).attributes) - end + milestones = client.milestones(repo, state: :all, per_page: 100) + milestones.each { |raw| MilestoneFormatter.new(project, raw).create! } true rescue ActiveRecord::RecordInvalid => e @@ -50,16 +48,15 @@ module Gitlab end def import_issues - client.list_issues(repo, state: :all, sort: :created, direction: :asc).each do |raw_data| - gh_issue = IssueFormatter.new(project, raw_data) + issues = client.issues(repo, state: :all, sort: :created, direction: :asc, per_page: 100) - if gh_issue.valid? - issue = Issue.create!(gh_issue.attributes) - apply_labels(gh_issue.number, issue) + issues.each do |raw| + gh_issue = IssueFormatter.new(project, raw) - if gh_issue.has_comments? - import_comments(gh_issue.number, issue) - end + if gh_issue.valid? + issue = gh_issue.create! + apply_labels(issue) + import_comments(issue) if gh_issue.has_comments? end end @@ -69,34 +66,48 @@ module Gitlab end def import_pull_requests - pull_requests = client.pull_requests(repo, state: :all, sort: :created, direction: :asc) - .map { |raw| PullRequestFormatter.new(project, raw) } - .select(&:valid?) + hooks = client.hooks(repo).map { |raw| HookFormatter.new(raw) }.select(&:valid?) + disable_webhooks(hooks) + + pull_requests = client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100) + pull_requests = pull_requests.map { |raw| PullRequestFormatter.new(project, raw) }.select(&:valid?) source_branches_removed = pull_requests.reject(&:source_branch_exists?).map { |pr| [pr.source_branch_name, pr.source_branch_sha] } target_branches_removed = pull_requests.reject(&:target_branch_exists?).map { |pr| [pr.target_branch_name, pr.target_branch_sha] } branches_removed = source_branches_removed | target_branches_removed - create_refs(branches_removed) + restore_branches(branches_removed) pull_requests.each do |pull_request| - merge_request = MergeRequest.new(pull_request.attributes) - - if merge_request.save - apply_labels(pull_request.number, merge_request) - import_comments(pull_request.number, merge_request) - import_comments_on_diff(pull_request.number, merge_request) - end + merge_request = pull_request.create! + apply_labels(merge_request) + import_comments(merge_request) + import_comments_on_diff(merge_request) end - delete_refs(branches_removed) - true rescue ActiveRecord::RecordInvalid => e raise Projects::ImportService::Error, e.message + ensure + clean_up_restored_branches(branches_removed) + clean_up_disabled_webhooks(hooks) + end + + def disable_webhooks(hooks) + update_webhooks(hooks, active: false) + end + + def clean_up_disabled_webhooks(hooks) + update_webhooks(hooks, active: true) + end + + def update_webhooks(hooks, options) + hooks.each do |hook| + client.edit_hook(repo, hook.id, hook.name, hook.config, options) + end end - def create_refs(branches) + def restore_branches(branches) branches.each do |name, sha| client.create_ref(repo, "refs/heads/#{name}", sha) end @@ -104,15 +115,15 @@ module Gitlab project.repository.fetch_ref(repo_url, '+refs/heads/*', 'refs/heads/*') end - def delete_refs(branches) + def clean_up_restored_branches(branches) branches.each do |name, _| client.delete_ref(repo, "heads/#{name}") project.repository.rm_branch(project.creator, name) end end - def apply_labels(number, issuable) - issue = client.issue(repo, number) + def apply_labels(issuable) + issue = client.issue(repo, issuable.iid) if issue.labels.count > 0 label_ids = issue.labels.map do |raw| @@ -123,20 +134,20 @@ module Gitlab end end - def import_comments(issue_number, noteable) - comments = client.issue_comments(repo, issue_number) - create_comments(comments, noteable) + def import_comments(issuable) + comments = client.issue_comments(repo, issuable.iid, per_page: 100) + create_comments(issuable, comments) end - def import_comments_on_diff(pull_request_number, merge_request) - comments = client.pull_request_comments(repo, pull_request_number) - create_comments(comments, merge_request) + def import_comments_on_diff(merge_request) + comments = client.pull_request_comments(repo, merge_request.iid, per_page: 100) + create_comments(merge_request, comments) end - def create_comments(comments, noteable) - comments.each do |raw_data| - comment = CommentFormatter.new(project, raw_data) - noteable.notes.create!(comment.attributes) + def create_comments(issuable, comments) + comments.each do |raw| + comment = CommentFormatter.new(project, raw) + issuable.notes.create!(comment.attributes) end end diff --git a/lib/gitlab/github_import/issue_formatter.rb b/lib/gitlab/github_import/issue_formatter.rb index c8173913b4e..835ec858b35 100644 --- a/lib/gitlab/github_import/issue_formatter.rb +++ b/lib/gitlab/github_import/issue_formatter.rb @@ -20,6 +20,10 @@ module Gitlab raw_data.comments > 0 end + def klass + Issue + end + def number raw_data.number end diff --git a/lib/gitlab/github_import/label_formatter.rb b/lib/gitlab/github_import/label_formatter.rb index c2b9d40b511..9f18244e7d7 100644 --- a/lib/gitlab/github_import/label_formatter.rb +++ b/lib/gitlab/github_import/label_formatter.rb @@ -9,6 +9,10 @@ module Gitlab } end + def klass + Label + end + private def color diff --git a/lib/gitlab/github_import/milestone_formatter.rb b/lib/gitlab/github_import/milestone_formatter.rb index e91a7e328cf..53d4b3102d1 100644 --- a/lib/gitlab/github_import/milestone_formatter.rb +++ b/lib/gitlab/github_import/milestone_formatter.rb @@ -14,6 +14,10 @@ module Gitlab } end + def klass + Milestone + end + private def number diff --git a/lib/gitlab/github_import/pull_request_formatter.rb b/lib/gitlab/github_import/pull_request_formatter.rb index a2947b56ad9..498b00cb658 100644 --- a/lib/gitlab/github_import/pull_request_formatter.rb +++ b/lib/gitlab/github_import/pull_request_formatter.rb @@ -24,6 +24,10 @@ module Gitlab } end + def klass + MergeRequest + end + def number raw_data.number end diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb index ab900b641c4..f751a3a12fd 100644 --- a/lib/gitlab/gon_helper.rb +++ b/lib/gitlab/gon_helper.rb @@ -8,6 +8,7 @@ module Gitlab gon.relative_url_root = Gitlab.config.gitlab.relative_url_root gon.shortcuts_path = help_shortcuts_path gon.user_color_scheme = Gitlab::ColorSchemes.for_user(current_user).css_class + gon.award_menu_url = emojis_path if current_user gon.current_user_id = current_user.id diff --git a/lib/gitlab/key_fingerprint.rb b/lib/gitlab/key_fingerprint.rb index baf52ff750d..8684b4636ea 100644 --- a/lib/gitlab/key_fingerprint.rb +++ b/lib/gitlab/key_fingerprint.rb @@ -17,9 +17,9 @@ module Gitlab file.rewind cmd = [] - cmd.push *%W(ssh-keygen) - cmd.push *%W(-E md5) if explicit_fingerprint_algorithm? - cmd.push *%W(-lf #{file.path}) + cmd.push('ssh-keygen') + cmd.push('-E', 'md5') if explicit_fingerprint_algorithm? + cmd.push('-lf', file.path) cmd_output, cmd_status = popen(cmd, '/tmp') end diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb index aff7ccb157f..f9bb5775323 100644 --- a/lib/gitlab/ldap/config.rb +++ b/lib/gitlab/ldap/config.rb @@ -93,6 +93,7 @@ module Gitlab end protected + def base_config Gitlab.config.ldap end diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index 356e96fcbab..78f3ecb4cb4 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -69,13 +69,20 @@ module Gitlab return unless ldap_person # If a corresponding person exists with same uid in a LDAP server, - # set up a Gitlab user with dual LDAP and Omniauth identities. - if user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider) - # Case when a LDAP user already exists in Gitlab. Add the Omniauth identity to existing account. + # check if the user already has a GitLab account. + user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider) + if user + # Case when a LDAP user already exists in Gitlab. Add the OAuth identity to existing account. + log.info "LDAP account found for user #{user.username}. Building new #{auth_hash.provider} identity." user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider) else - # No account in Gitlab yet: create it and add the LDAP identity - user = build_new_user + log.info "No existing LDAP account was found in GitLab. Checking for #{auth_hash.provider} account." + user = find_by_uid_and_provider + if user.nil? + log.info "No user found using #{auth_hash.provider} provider. Creating a new one." + user = build_new_user + end + log.info "Correct account has been found. Adding LDAP identity to user: #{user.username}." user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn) end diff --git a/lib/gitlab/saml/user.rb b/lib/gitlab/saml/user.rb index dba4bbfc899..8943022612c 100644 --- a/lib/gitlab/saml/user.rb +++ b/lib/gitlab/saml/user.rb @@ -12,12 +12,12 @@ module Gitlab end def gl_user - @user ||= find_by_uid_and_provider - if auto_link_ldap_user? @user ||= find_or_create_ldap_user end + @user ||= find_by_uid_and_provider + if auto_link_saml_user? @user ||= find_by_email end diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb index 2ef0e982256..7cf506ebe64 100644 --- a/lib/gitlab/seeder.rb +++ b/lib/gitlab/seeder.rb @@ -5,7 +5,7 @@ module Gitlab SeedFu.quiet = true yield SeedFu.quiet = false - puts "\nOK".green + puts "\nOK".color(:green) end def self.by_user(user) diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb index c3ddd4c2680..388f84dbe0e 100644 --- a/lib/gitlab/workhorse.rb +++ b/lib/gitlab/workhorse.rb @@ -6,6 +6,13 @@ module Gitlab SEND_DATA_HEADER = 'Gitlab-Workhorse-Send-Data' class << self + def git_http_ok(repository, user) + { + 'GL_ID' => Gitlab::ShellEnv.gl_id(user), + 'RepoPath' => repository.path_to_repo, + } + end + def send_git_blob(repository, blob) params = { 'RepoPath' => repository.path_to_repo, @@ -14,24 +21,39 @@ module Gitlab [ SEND_DATA_HEADER, - "git-blob:#{encode(params)}", + "git-blob:#{encode(params)}" ] end - def send_git_archive(project, ref, format) + def send_git_archive(repository, ref:, format:) format ||= 'tar.gz' format.downcase! - params = project.repository.archive_metadata(ref, Gitlab.config.gitlab.repository_downloads_path, format) + params = repository.archive_metadata(ref, Gitlab.config.gitlab.repository_downloads_path, format) raise "Repository or ref not found" if params.empty? [ SEND_DATA_HEADER, - "git-archive:#{encode(params)}", + "git-archive:#{encode(params)}" ] end - + + def send_git_diff(repository, diff_refs) + from, to = diff_refs + + params = { + 'RepoPath' => repository.path_to_repo, + 'ShaFrom' => from.sha, + 'ShaTo' => to.sha + } + + [ + SEND_DATA_HEADER, + "git-diff:#{encode(params)}" + ] + end + protected - + def encode(hash) Base64.urlsafe_encode64(JSON.dump(hash)) end |