From 4974d0297cff29aa3d3731782e0fc661be31530b Mon Sep 17 00:00:00 2001 From: Luke Shumaker 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