From 735563329d1f86ee4d72b37cd22eed1168935e8e Mon Sep 17 00:00:00 2001 From: James Lopez <james@jameslopez.es> Date: Mon, 7 Mar 2016 12:50:35 +0100 Subject: [PATCH] refactored a bunch of stuff based on MR feedback --- app/models/project_import_data.rb | 2 +- ...8_remove_wrong_import_url_from_projects.rb | 38 +++++++++++-------- lib/gitlab/github_import/importer.rb | 4 +- lib/gitlab/github_import/project_creator.rb | 3 +- lib/gitlab/import_url_exposer.rb | 14 +++---- spec/lib/gitlab/import_url_exposer_spec.rb | 13 +++++++ 6 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 spec/lib/gitlab/import_url_exposer_spec.rb diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb index 23f4e97b8aa..f3b9daa0d1a 100644 --- a/app/models/project_import_data.rb +++ b/app/models/project_import_data.rb @@ -12,7 +12,7 @@ require 'file_size_validator' class ProjectImportData < ActiveRecord::Base belongs_to :project - attr_encrypted :credentials, key: Gitlab::Application.secrets.db_key_base, marshal: true + attr_encrypted :credentials, key: Gitlab::Application.secrets.db_key_base, marshal: true, encode: true serialize :data, JSON diff --git a/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb b/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb index dfa9f2d4dee..881af783c61 100644 --- a/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb +++ b/db/migrate/20160302152808_remove_wrong_import_url_from_projects.rb @@ -2,43 +2,49 @@ class RemoveWrongImportUrlFromProjects < ActiveRecord::Migration class ImportUrlSanitizer def initialize(url) - @url = url + @url = URI.parse(url) end def sanitized_url - @sanitized_url ||= @url[regex_extractor, 1] + @url[regex_extractor, 3] + @sanitized_url ||= safe_url end def credentials - @credentials ||= @url[regex_extractor, 2] + @credentials ||= { user: @url.user, password: @url.password } end private - # Regex matches 1 <first part of URL>, 2 <token or to be encrypted stuff>, - # 3 <last part of URL> - def regex_extractor - /(.*\/\/)(.*)(\@.*)/ + def safe_url + safe_url = @url.dup + safe_url.password = nil + safe_url.user = nil + safe_url end + + end + + class FakeProjectImportData + extend AttrEncrypted + attr_accessor :credentials + attr_encrypted :credentials, key: Gitlab::Application.secrets.db_key_base, marshal: true, encode: true end def up - projects_with_wrong_import_url.each do |project_id| - project = Project.find(project_id["id"]) - sanitizer = ImportUrlSanitizer.new(project.import_url) + projects_with_wrong_import_url.each do |project| + sanitizer = ImportUrlSanitizer.new(project["import_url"]) ActiveRecord::Base.transaction do - project.update_columns(import_url: sanitizer.sanitized_url) - if project.import_data - project.import_data.credentials = sanitizer.credentials - project.save! - end + execute("UPDATE projects SET import_url = '#{sanitizer.sanitized_url}' WHERE id = #{project['id']}") + fake_import_data = FakeProjectImportData.new + fake_import_data.credentials = sanitizer.credentials + execute("UPDATE project_import_data SET encrypted_credentials = '#{fake_import_data.encrypted_credentials}' WHERE project_id = #{project['id']}") end end end def projects_with_wrong_import_url # TODO Check live with #operations for possible false positives. Also, consider regex? But may have issues MySQL/PSQL - select_all("SELECT p.id from projects p WHERE p.import_url LIKE '%//%:%@%' or p.import_url like '#{"_"*40}@github.com%'") + select_all("SELECT p.id, p.import_url from projects p WHERE p.import_url LIKE '%//%:%@%' or p.import_url like '#{"_"*40}@github.com%'") end end diff --git a/lib/gitlab/github_import/importer.rb b/lib/gitlab/github_import/importer.rb index 515fd4720d5..d478d3b5398 100644 --- a/lib/gitlab/github_import/importer.rb +++ b/lib/gitlab/github_import/importer.rb @@ -7,8 +7,8 @@ module Gitlab def initialize(project) @project = project - github_session = project.import_data.credentials if import_data - @client = Client.new(github_session["github_access_token"]) + credentials = project.import_data.credentials if import_data + @client = Client.new(credentials["github_access_token"]) @formatter = Gitlab::ImportFormatter.new end diff --git a/lib/gitlab/github_import/project_creator.rb b/lib/gitlab/github_import/project_creator.rb index b5ed32e5b1e..52aba93a51d 100644 --- a/lib/gitlab/github_import/project_creator.rb +++ b/lib/gitlab/github_import/project_creator.rb @@ -32,8 +32,7 @@ module Gitlab def create_import_data(project) project.create_import_data( - credentials: { github_access_token: session_data.delete(:github_access_token) }, - data: { github_session: session_data }) + credentials: { github_access_token: session_data.delete(:github_access_token) }) end end end diff --git a/lib/gitlab/import_url_exposer.rb b/lib/gitlab/import_url_exposer.rb index f1919dffa8a..bf03f5a6daf 100644 --- a/lib/gitlab/import_url_exposer.rb +++ b/lib/gitlab/import_url_exposer.rb @@ -2,16 +2,12 @@ module Gitlab # Exposes an import URL that includes the credentials unencrypted. # Extracted to its own class to prevent unintended use. module ImportUrlExposer - extend self - def expose(import_url:, credentials: ) - import_url.sub("//", "//#{parsed_credentials(credentials)}@") - end - - private - - def parsed_credentials(credentials) - credentials.values.join(":") + def self.expose(import_url:, credentials: ) + uri = URI.parse(import_url) + uri.user = credentials[:user] + uri.password = credentials[:password] + uri end end end diff --git a/spec/lib/gitlab/import_url_exposer_spec.rb b/spec/lib/gitlab/import_url_exposer_spec.rb new file mode 100644 index 00000000000..878947caea1 --- /dev/null +++ b/spec/lib/gitlab/import_url_exposer_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe 'Gitlab::ImportUrlExposer' do + + describe :expose do + let(:credentials) do + Gitlab::ImportUrlExposer.expose(import_url: "https://github.com/me/project.git", credentials: {user: 'blah', password: 'password'}) + end + + it { expect(credentials).to be_a(URI) } + it { expect(credentials.to_s).to eq("https://blah:password@github.com/me/project.git") } + end +end -- GitLab