summaryrefslogtreecommitdiff
path: root/backends/gitlab-ee
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-12-15 02:07:07 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-12-15 02:07:07 -0500
commit4974d0297cff29aa3d3731782e0fc661be31530b (patch)
tree916dbcf7e1428b410549a6d8ebab4adeafc50917 /backends/gitlab-ee
parent81092fa4520971697d47e6a5d498d3cbd785adaa (diff)
wip
Diffstat (limited to 'backends/gitlab-ee')
-rwxr-xr-xbackends/gitlab-ee99
1 files changed, 99 insertions, 0 deletions
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