refactored a bunch of stuff based on MR feedback
This commit is contained in:
parent
7085850c50
commit
735563329d
|
@ -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
|
||||
|
||||
|
|
|
@ -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 @@ 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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue