some refactoring based on feedback

This commit is contained in:
James Lopez 2016-03-21 13:15:51 +01:00
parent 5f86912ef0
commit 383cc84047
7 changed files with 61 additions and 49 deletions

View file

@ -404,6 +404,18 @@ class Project < ActiveRecord::Base
self.import_data.destroy if self.import_data self.import_data.destroy if self.import_data
end end
def import_url=(value)
sanitizer = Gitlab::ImportUrlSanitizer.new(value)
self[:import_url] = sanitizer.sanitized_url
create_import_data(credentials: sanitizer.credentials)
end
def import_url
if import_data
Gitlab::ImportUrlExposer.expose(import_url: self[:import_url], credentials: import_data.credentials)
end
end
def import? def import?
external_import? || forked? external_import? || forked?
end end

View file

@ -1,29 +1,5 @@
class RemoveWrongImportUrlFromProjects < ActiveRecord::Migration class RemoveWrongImportUrlFromProjects < ActiveRecord::Migration
class ImportUrlSanitizer
def initialize(url)
@url = URI.parse(url)
end
def sanitized_url
@sanitized_url ||= safe_url
end
def credentials
@credentials ||= { user: @url.user, password: @url.password }
end
private
def safe_url
safe_url = @url.dup
safe_url.password = nil
safe_url.user = nil
safe_url
end
end
class FakeProjectImportData class FakeProjectImportData
extend AttrEncrypted extend AttrEncrypted
attr_accessor :credentials attr_accessor :credentials
@ -31,20 +7,30 @@ class RemoveWrongImportUrlFromProjects < ActiveRecord::Migration
end end
def up def up
projects_with_wrong_import_url.each do |project| projects_with_wrong_import_url.find_in_batches do |project_batch|
sanitizer = ImportUrlSanitizer.new(project["import_url"]) project_batch.each do |project|
sanitizer = Gitlab::ImportUrlSanitizer.new(project["import_url"])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
execute("UPDATE projects SET import_url = '#{sanitizer.sanitized_url}' WHERE id = #{project['id']}") execute("UPDATE projects SET import_url = '#{quote(sanitizer.sanitized_url)}' WHERE id = #{project['id']}")
fake_import_data = FakeProjectImportData.new fake_import_data = FakeProjectImportData.new
fake_import_data.credentials = sanitizer.credentials fake_import_data.credentials = sanitizer.credentials
execute("UPDATE project_import_data SET encrypted_credentials = '#{fake_import_data.encrypted_credentials}' WHERE project_id = #{project['id']}") execute("UPDATE project_import_data SET encrypted_credentials = '#{quote(fake_import_data.encrypted_credentials)}' WHERE project_id = #{project['id']}")
end
end end
end end
end end
def down
end
def projects_with_wrong_import_url def projects_with_wrong_import_url
# TODO Check live with #operations for possible false positives. Also, consider regex? But may have issues MySQL/PSQL # TODO Check live with #operations for possible false positives. Also, consider regex? But may have issues MySQL/PSQL
select_all("SELECT p.id, p.import_url 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 IS NOT NULL AND (p.import_url LIKE '%//%:%@%' OR p.import_url LIKE '#{"_"*40}@github.com%')")
end
def quote(value)
ActiveRecord::Base.connection.quote(value)
end end
end end

View file

@ -416,7 +416,7 @@ ActiveRecord::Schema.define(version: 20160316204731) do
t.string "state" t.string "state"
t.integer "iid" t.integer "iid"
t.integer "updated_by_id" t.integer "updated_by_id"
t.boolean "confidential", default: false t.boolean "confidential", default: false
end end
add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree
@ -684,6 +684,8 @@ ActiveRecord::Schema.define(version: 20160316204731) do
create_table "project_import_data", force: :cascade do |t| create_table "project_import_data", force: :cascade do |t|
t.integer "project_id" t.integer "project_id"
t.text "data" t.text "data"
t.text "encrypted_credentials"
t.text "encrypted_credentials_iv"
end end
create_table "projects", force: :cascade do |t| create_table "projects", force: :cascade do |t|

View file

@ -8,7 +8,7 @@ module Gitlab
def initialize(project) def initialize(project)
@project = project @project = project
credentials = project.import_data.credentials if import_data credentials = project.import_data.credentials if import_data
@client = Client.new(credentials["github_access_token"]) @client = Client.new(credentials[:user])
@formatter = Gitlab::ImportFormatter.new @formatter = Gitlab::ImportFormatter.new
end end

View file

@ -11,7 +11,7 @@ module Gitlab
end end
def execute def execute
project = ::Projects::CreateService.new( ::Projects::CreateService.new(
current_user, current_user,
name: repo.name, name: repo.name,
path: repo.name, path: repo.name,
@ -20,19 +20,9 @@ module Gitlab
visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : Gitlab::VisibilityLevel::PUBLIC, visibility_level: repo.private ? Gitlab::VisibilityLevel::PRIVATE : Gitlab::VisibilityLevel::PUBLIC,
import_type: "github", import_type: "github",
import_source: repo.full_name, import_source: repo.full_name,
import_url: repo.clone_url, import_url: repo.clone_url.sub("https://", "https://#{@session_data[:github_access_token]}@"),
wiki_enabled: !repo.has_wiki? # If repo has wiki we'll import it later wiki_enabled: !repo.has_wiki? # If repo has wiki we'll import it later
).execute ).execute
create_import_data(project)
project
end
private
def create_import_data(project)
project.create_import_data(
credentials: { github_access_token: session_data.delete(:github_access_token) })
end end
end end
end end

View file

@ -12,9 +12,7 @@ module Gitlab
end end
def import_url def import_url
import_url = Gitlab::ImportUrlExposer.expose(import_url: project.import_url, project.import_url.import_url.sub(/\.git\z/, ".wiki.git")
credentials: project.import_data.credentials)
import_url.sub(/\.git\z/, ".wiki.git")
end end
end end
end end

View file

@ -0,0 +1,24 @@
module Gitlab
class ImportUrlSanitizer
def initialize(url)
@url = URI.parse(url)
end
def sanitized_url
@sanitized_url ||= safe_url.to_s
end
def credentials
@credentials ||= { user: @url.user, password: @url.password }
end
private
def safe_url
safe_url = @url.dup
safe_url.password = nil
safe_url.user = nil
safe_url
end
end
end