From 4974d0297cff29aa3d3731782e0fc661be31530b Mon Sep 17 00:00:00 2001
From: Luke Shumaker <lukeshu@sbcglobal.net>
Date: Thu, 15 Dec 2016 02:07:07 -0500
Subject: wip

---
 backends/gitlab-ee | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100755 backends/gitlab-ee

(limited to 'backends/gitlab-ee')

diff --git a/backends/gitlab-ee b/backends/gitlab-ee
new file mode 100755
index 0000000..d0db8b9
--- /dev/null
+++ b/backends/gitlab-ee
@@ -0,0 +1,99 @@
+#!/usr/bin/env ruby
+# coding: utf-8
+
+# GitLab EE supports configuring a "project" (GitLab's term for a
+# repository+metadata) to display as a mirror of another repository.
+#
+#     http://docs.gitlab.com/ee/workflow/repository_mirroring.html
+#
+# Unfortunately, the JSON API doesn't support this
+#
+#     https://gitlab.com/gitlab-org/gitlab-ee/issues/767
+#
+# So, we must use the (undocumented!) HTTP API, which is actually
+# pretty clean, except that screen-scraping the reads (via nokogiri)
+# is gross, and that the error messages are unhelpful.
+
+load 'gitlab-ce'
+require 'net/http'
+require 'uri'
+require 'nokogiri'
+
+class GitLabEE < GitLabCE
+	def _mirrorURL
+		unless @cache.has_key?(:mirror)
+			req = Net::HTTP::Get.new(URI(_info["web_url"]+"/mirror"))
+			req.add_field("PRIVATE-TOKEN", @api_key)
+			con = _connection(req.uri)
+			res = con.request(req)
+			if res.code != "200"
+				throw res
+			end
+			@cache[:mirror_res]=res
+			doc = Nokogiri::HTML(res.body)
+
+			@cache[:mirror_cookie] = res["set-cookie"]
+			@cache[:mirror_token] = doc.css('input[name="authenticity_token"]').first["value"]
+			is_mirror = doc.css("#project_mirror").first["checked"]
+			if !is_mirror
+				@cache[:mirror] = nil
+			else
+				@cache[:mirror] = URI(doc.css("#project_import_url").first["value"])
+			end
+		end
+		return @cache[:mirror]
+	end
+
+	def _mirrorURL=(url)
+		_mirrorURL
+
+		req = Net::HTTP::Patch.new(URI(_info["web_url"]+"/mirror"))
+		req.add_field("PRIVATE-TOKEN", @api_key) # authenticate
+		req.add_field("Cookie", @cache[:mirror_cookie]) # session id
+		req.form_data = {
+			"utf8" => "✓",
+			"authenticity_token" => @cache[:mirror_token], # session state
+			"project[mirror]" => (url.nil? ? "0" : "1"),
+			"project[import_url]" => url.to_s,
+		}
+
+		con = _connection(req.uri)
+		res = con.request(req)
+		if res.code != "302"
+			throw res
+		end
+
+		@cache.delete(:mirror)
+		@cache.delete(:mirror_token)
+		@cache.delete(:mirror_cookie)
+		return URI(url)
+	end
+	
+	def get_meta
+		map = super
+		map["mirror"] = _mirrorURL.to_s
+		return map
+	end
+
+	def set_meta(map)
+		if map.has_key?("mirror")
+			self._mirrorURL=map["mirror"]
+			map.delete("mirror")
+		end
+		return super(map)
+	end
+
+	def create(id, map)
+		super(id, map)
+		self._mirrorURL=map["mirror"]
+	end
+
+	def capabilities
+		return super.map{|c|
+			if c[0] == "get-meta" or c[0] == "set-meta"
+				c << "mirror"
+			end
+			c
+		}
+	end
+end
-- 
cgit v1.2.3-2-g168b