Commit 73556332 authored by James Lopez's avatar James Lopez
Browse files

refactored a bunch of stuff based on MR feedback

parent 417bfbcac92b
......@@ -12,7 +12,7 @@
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
......
......@@ -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
......@@ -7,8 +7,8 @@ class Importer
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
......
......@@ -32,8 +32,7 @@ def execute
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
......
......@@ -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
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
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