require 'uri' require 'net/http' require "json" NO_GITHUB_ORGANISATION_PROVIDED = 'No Github organisations have been set in your configuration' NO_ORGANISATION_MEMBER_KEYS_FOUND = 'There are no public members for this Github organisation' namespace :security do desc 'Cycle SSH key logins' task :update_ssh_keys do run_locally do organisations = fetch(:github_orgs) || fetch(:github_org) || raise(NO_GITHUB_ORGANISATION_PROVIDED) keys = "" authentication = '' if fetch(:github_app_id) && fetch(:github_app_secret) authentication = "#{fetch(:github_app_id)}:#{fetch(:github_app_secret)}@" end [*organisations].each do |organisation| info "Fetching keys for #{organisation}" url = URI("https://#{authentication}api.github.com/orgs/#{organisation}") organisation_details = JSON.parse(Net::HTTP.get_response(url).body, symbolize_names: true) members_url = URI(organisation_details[:members_url].gsub("{/member}", "").gsub('https://', "https://#{authentication}")) response = Net::HTTP.get_response(members_url) raise response.body unless response.kind_of? Net::HTTPSuccess members = JSON.parse(response.body, symbolize_names: true) keys += "\n#\n"\ "# #{organisation_details[:name]} keys\n"\ "# #{members_url}\n"\ "#\n" member_details = members.map { |member| member[:login].downcase }.sort member_details.each do |member| info " - Downloading keys for #{member}" member_keys = URI("https://#{authentication}github.com/#{member}.keys") info = "\n #\n"\ " # @#{member}\n"\ " # #{member_keys}\n"\ " #\n" response = Net::HTTP.get_response(member_keys) raise response.body unless response.kind_of? Net::HTTPSuccess keys += info + response.body.gsub(/\r\n?/, "\n") end end raise raise NO_ORGANISATION_MEMBER_KEYS_FOUND unless keys.scan(/ssh-(rsa|ed25519)/).count > 0 info "Writing authorized_keys file to ./tmp" File.open("./tmp/authorized_keys", "w") do |f| f.write(keys) end info "Uploading updated authorized_keys to servers" on roles(:all) do |host| upload! './tmp/authorized_keys', "/tmp/authorized_keys" execute :mv, "/tmp/authorized_keys", "~/.ssh/authorized_keys" end end end end