gitall 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +9 -0
- data/.travis.yml +46 -0
- data/Gemfile +3 -0
- data/README.md +7 -0
- data/bin/gitall +3 -58
- data/example.gitall-rc.yml +51 -0
- data/gitall.gemspec +47 -0
- data/lib/gitall/cli/app.rb +28 -0
- data/lib/gitall/cli/runner.rb +51 -0
- data/lib/gitall/version.rb +1 -1
- data/lib/{views → gitall/views}/_403.erb +0 -0
- data/lib/gitall.rb +225 -0
- metadata +113 -8
- data/lib/cli/app.rb +0 -0
- data/lib/gitall/gitall.rb +0 -200
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0763f90c0ee820e5a98183f8bbba0bb8d3d00732c088f1423fe3db65851e7e8
|
4
|
+
data.tar.gz: c98f7711d1e403332ba5708a92b0d15f9a5c2197a67a835d190c39c11addd1e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7423b7049c516acdd56feabb213b407d98dfa66c31ae6692e14940c1b839af26efce57c8c930b48128b082caf11692f65be45b6c126cef4dee0c65addcf7784
|
7
|
+
data.tar.gz: 88eb76e81a7eea9001a8fb4ed7a06078d66cc193db51e3f5eac17db0661d383a2dea698efd86d31ec5311e8fc08e5b3a47dd0a7a012e22a06382277fc57c909b
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
language: ruby
|
2
|
+
script: echo "Running tests against $(ruby -v) ..."
|
3
|
+
bundler_args: --jobs=6 --retry=3 --standalone
|
4
|
+
notifications:
|
5
|
+
irc:
|
6
|
+
channels:
|
7
|
+
- ircs://irc.electrocode.net:6697/#commits
|
8
|
+
template:
|
9
|
+
- "%{repository_slug}#%{build_number} (%{branch} - %{commit}) %{author}): %{message}"
|
10
|
+
- 'Change view : %{compare_url}'
|
11
|
+
- 'Build details : %{build_url}'
|
12
|
+
skip_join: true
|
13
|
+
jobs:
|
14
|
+
include:
|
15
|
+
- stage: test Ruby2.2
|
16
|
+
rvm: 2.2.7
|
17
|
+
script:
|
18
|
+
- echo "Running tests against $(ruby -v) ..."
|
19
|
+
- bundle exec rake -t
|
20
|
+
- stage: test Ruby2.3
|
21
|
+
rvm: 2.3.4
|
22
|
+
script:
|
23
|
+
- echo "Running tests against $(ruby -v) ..."
|
24
|
+
- bundle exec rake -t
|
25
|
+
- stage: test Ruby2.4
|
26
|
+
rvm: 2.4.1
|
27
|
+
script:
|
28
|
+
- echo "Running tests against $(ruby -v) ..."
|
29
|
+
- bundle exec rake -t
|
30
|
+
- stage: test Ruby2.5
|
31
|
+
rvm: 2.5.0
|
32
|
+
script:
|
33
|
+
- echo "Running tests against $(ruby -v) ..."
|
34
|
+
- bundle exec rake -t
|
35
|
+
- stage: gem release
|
36
|
+
rvm: 2.3.0
|
37
|
+
script: echo "Deploying to rubygems.org ..."
|
38
|
+
deploy:
|
39
|
+
provider: rubygems
|
40
|
+
api_key:
|
41
|
+
secure: BJd+CDvEsqGIB04QiLTr/+xZp9BzhyIZTcAfMWc84SE88jM/PgvklIujWgFTL7ZU1perK38t6PUdWUkiNzSfrIidfzFeRgQRGY9jN2hnxf9isHtkS2Dz75xMCBGaLlC8FmRd/CdftepG8Hd5VzUYCcwbKDOtDnHINhJWQ4RV6m0csf4qkK2vmJXhbuvblsLMwpk5NqNWhf2boQp6URuy7kbIvmGlfqDLULhQpv0ScgRmcogMePeOOGgLB5kWuRwMZUy5jIrhtumd6w1G0E93eqU7P28CL/usQvd+aOygyYJ02lR6cgzhcWd2ldtCCctqjazobQhz8lwqr7m+DHx+Px2JkwBw+XUAkceIuFl+As29/5PSULTmU2+DjjH1QXUXCa566lu8wCN6ZaJIGfgiV1BQzapomCDq8xviNIVKqeWDZ6zL4axAJ22VWfck2m3T4ZPon5qf8+uX1/pGJF6LI7S243Ee52G6GPjPzw1EgsVojliYAjoLIRM6vusLJo0NZzy7BrPUYtNd3KeTdaJE5J7hBhLHrkaZ64RC1Gt2pCT9uLQVv9+oezycS5AdNSeT1C+D//4/XbkhjrppLZBc9f8PC9o5HYHkwvCWdQLv61/3bhZTSCJ4K9H7lfmF58z9E7/891NGeMrJWeTsFsTX60StwooHmRKAy1duUL6SDL4=
|
42
|
+
gem: gitall
|
43
|
+
on:
|
44
|
+
tags: true
|
45
|
+
repo: IotaSpencer/gitall
|
46
|
+
branch: master
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# GitAll
|
2
|
+
|
3
|
+
This is a Ruby+Sinatra mini-app that catches Web Based Git Services' webhooks and returns them to an IRC channel.
|
4
|
+
|
5
|
+
To use, you install the gem, which is actually in a fairly alpha gem stage after being ported to a gem from a standalone bot that would've just been cloned.
|
6
|
+
|
7
|
+
If you want to be entered into the already running hook, please use [this (**not working**)](https://e-code.in/gitall-form)
|
data/bin/gitall
CHANGED
@@ -1,58 +1,3 @@
|
|
1
|
-
#! /usr/bin/
|
2
|
-
|
3
|
-
|
4
|
-
require 'sinatra/base'
|
5
|
-
require 'json'
|
6
|
-
require 'cinch'
|
7
|
-
require 'cinch/plugins/basic_ctcp'
|
8
|
-
require 'cinch/plugins/identify'
|
9
|
-
require 'ostruct'
|
10
|
-
require 'recursive-open-struct'
|
11
|
-
require 'yaml'
|
12
|
-
require 'unirest'
|
13
|
-
require 'base64'
|
14
|
-
require 'active_support/all'
|
15
|
-
Thread.abort_on_exception = true
|
16
|
-
|
17
|
-
# @note Load the plugins
|
18
|
-
require 'gitallchancontrol.rb'
|
19
|
-
require './lib/admin.rb'
|
20
|
-
require './lib/logger.rb'
|
21
|
-
require './lib/eval.rb'
|
22
|
-
|
23
|
-
# @note Load the parsers
|
24
|
-
require 'gitall/parsers/gitlab'
|
25
|
-
require 'gitall/parsers/github.rb'
|
26
|
-
|
27
|
-
# Cinch
|
28
|
-
|
29
|
-
$cfg = YAML.load_file(`echo ~/.gitall-rc.yml`.chomp!)
|
30
|
-
$bots = Hash.new
|
31
|
-
$threads = Array.new
|
32
|
-
|
33
|
-
# For the sake of this example, we'll create an ORM-like model and give it an
|
34
|
-
# authenticate method, that checks if a given password matches.
|
35
|
-
class User < Struct.new :nickname, :password, :type
|
36
|
-
def authenticate(pass)
|
37
|
-
password == pass
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Simulate a database.
|
42
|
-
$users = []
|
43
|
-
@users = YAML.load_file(`echo ~/.gitall-rc.yml`.chomp!)['users']
|
44
|
-
@users.each do |user, hash|
|
45
|
-
password = hash['password']
|
46
|
-
role = hash['role']
|
47
|
-
$users << User.new(user, password, role)
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
$bots.each do |key, bot|
|
52
|
-
puts "Starting IRC connection for #{key}..."
|
53
|
-
$threads << Thread.new { bot.start }
|
54
|
-
end
|
55
|
-
$threads << Thread.new {
|
56
|
-
WebHook.run! if __FILE__ == $PROGRAM_NAME
|
57
|
-
}
|
58
|
-
$threads.each(&:join)
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
require 'gitall/cli/runner'
|
3
|
+
GitAll::App::Runner.new(ARGV).execute!
|
@@ -0,0 +1,51 @@
|
|
1
|
+
api-key: ...
|
2
|
+
users:
|
3
|
+
USER1:
|
4
|
+
password: SOMEPASSWORDHERE
|
5
|
+
role: admin
|
6
|
+
networks:
|
7
|
+
netname1:
|
8
|
+
server: irc.server.net
|
9
|
+
port: 6697
|
10
|
+
ssl: true
|
11
|
+
sslverify: false
|
12
|
+
nickname: GitLabIRC
|
13
|
+
username: Git
|
14
|
+
realname: https://gitlab.com/gitall/gitall
|
15
|
+
mps: 3.0 # messages_per_second
|
16
|
+
# most regular networks allow sasl PLAIN
|
17
|
+
prefix: '^!'
|
18
|
+
sasl-username: accountname
|
19
|
+
sasl-password: password
|
20
|
+
# CERTFP / SASL EXTERNAL
|
21
|
+
certpath: /path/to/cert.pem
|
22
|
+
netname2:
|
23
|
+
server: irc.server.net
|
24
|
+
port: 6697
|
25
|
+
ssl: true
|
26
|
+
sslverify: false
|
27
|
+
nickname: GitLabIRC
|
28
|
+
username: Git
|
29
|
+
realname: https://gitlab.com/gitall/gitall
|
30
|
+
prefix: '^@'
|
31
|
+
mps: 3.0 # messages_per_second
|
32
|
+
identify-with: none
|
33
|
+
# network where you don't identify
|
34
|
+
projects:
|
35
|
+
"owner/project":
|
36
|
+
host: gitlab # github, gitlab, bitbucket
|
37
|
+
token: 56H15G1DF5G1DFG5D161GD
|
38
|
+
channels:
|
39
|
+
"#channel1,network1":
|
40
|
+
option1: true
|
41
|
+
#key: orly
|
42
|
+
"owner/project2":
|
43
|
+
host: gitlab # github, gitlab, bitbucket
|
44
|
+
token: DFG4DF56G4G56D4FG65FG4
|
45
|
+
channels:
|
46
|
+
"#channel1,network1":
|
47
|
+
option1: true
|
48
|
+
#key: orly
|
49
|
+
"#channel2,network2":
|
50
|
+
option1: true
|
51
|
+
#key: orly
|
data/gitall.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'gitall/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |s|
|
9
|
+
s.name = "gitall"
|
10
|
+
s.version = GitAll::VERSION
|
11
|
+
s.authors = ["Ken Spencer"]
|
12
|
+
s.email = ["me@iotaspencer.me"]
|
13
|
+
s.homepage = "https://iotaspencer.me/projects/gitall"
|
14
|
+
s.summary = "Git Based Webservices Webhook Receiver"
|
15
|
+
s.description = "A git based webhook receiver for GitHub, GitLab, and Gogs"
|
16
|
+
s.license = 'MIT'
|
17
|
+
|
18
|
+
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test)/})
|
20
|
+
end
|
21
|
+
s.platform = Gem::Platform::RUBY
|
22
|
+
s.require_paths = ['lib']
|
23
|
+
|
24
|
+
s.required_ruby_version = '~> 2'
|
25
|
+
s.bindir = 'bin'
|
26
|
+
s.executables << 'gitall'
|
27
|
+
|
28
|
+
s.add_runtime_dependency 'cinch', '~> 2.3'
|
29
|
+
s.add_runtime_dependency 'cinch-authentication', '~> 0.1.1'
|
30
|
+
s.add_runtime_dependency 'cinch-identify', '~> 1.7'
|
31
|
+
s.add_runtime_dependency 'cinch-basic_ctcp', '~> 1.1'
|
32
|
+
s.add_runtime_dependency 'sinatra', '~> 2.0', '>= 2.0.2'
|
33
|
+
s.add_runtime_dependency 'sinatra-contrib', '~> 2.0.2', '>= 2.0.2'
|
34
|
+
s.add_runtime_dependency 'recursive-open-struct', '~> 1.1'
|
35
|
+
s.add_runtime_dependency 'activesupport', '~> 5.2'
|
36
|
+
s.add_runtime_dependency 'unirest', '~> 1.1'
|
37
|
+
s.add_runtime_dependency 'strgen', '~> 0.1'
|
38
|
+
s.add_runtime_dependency 'thor', '~> 0.20'
|
39
|
+
s.add_runtime_dependency 'paint', '~> 2.0'
|
40
|
+
s.add_runtime_dependency 'git', '~> 1.3'
|
41
|
+
s.add_runtime_dependency 'logging', '~> 2.2'
|
42
|
+
s.add_runtime_dependency 'pry', '~> 0.11'
|
43
|
+
|
44
|
+
s.add_development_dependency 'bundler', '~> 1.16'
|
45
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
46
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
47
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'gitall'
|
3
|
+
module GitAll
|
4
|
+
|
5
|
+
class CLI < Thor
|
6
|
+
desc 'init [options]', 'Initialize the gem.'
|
7
|
+
def init
|
8
|
+
if Pathname(Dir.home).join('.gitall-rc.yml').exist?
|
9
|
+
say "Error: #{Pathname(Dir.home).join('.gitall-rc.yml')} exists, not overwriting."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'start [options]', 'Start GitAll'
|
14
|
+
def start
|
15
|
+
threads = []
|
16
|
+
GitAll::Bot::Bots.add_bots
|
17
|
+
GitAll::Bot::Bots.bots.each do |name, bot|
|
18
|
+
threads << Thread.new do
|
19
|
+
bot.start
|
20
|
+
Thread.current.thread_variable_set(:network, name)
|
21
|
+
Thread.current.thread_variable_set(:bot, bot)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
threads << Thread.new { GitAll::WebHook.run! }
|
25
|
+
threads.each(&:join)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'gitall/cli/app'
|
2
|
+
|
3
|
+
module GitAll
|
4
|
+
module App
|
5
|
+
class Runner
|
6
|
+
# Allow everything fun to be injected from the outside while defaulting to normal implementations.
|
7
|
+
def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
|
8
|
+
@argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute!
|
12
|
+
exit_code = begin
|
13
|
+
# Thor accesses these streams directly rather than letting them be injected, so we replace them...
|
14
|
+
$stderr = @stderr
|
15
|
+
$stdin = @stdin
|
16
|
+
$stdout = @stdout
|
17
|
+
|
18
|
+
# Run our normal Thor app the way we know and love.
|
19
|
+
GitAll::CLI.start(@argv)
|
20
|
+
|
21
|
+
# Thor::Base#start does not have a return value, assume success if no exception is raised.
|
22
|
+
0
|
23
|
+
rescue StandardError => e
|
24
|
+
# The ruby interpreter would pipe this to STDERR and exit 1 in the case of an unhandled exception
|
25
|
+
b = e.backtrace
|
26
|
+
@stderr.puts("#{b.shift}: #{e.message} (#{e.class})")
|
27
|
+
@stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
|
28
|
+
1
|
29
|
+
rescue SystemExit => e
|
30
|
+
e.status
|
31
|
+
ensure
|
32
|
+
# TODO: reset your app here, free up resources, etc.
|
33
|
+
# Examples:
|
34
|
+
# MyApp.logger.flush
|
35
|
+
# MyApp.logger.close
|
36
|
+
# MyApp.logger = nil
|
37
|
+
#
|
38
|
+
# MyApp.reset_singleton_instance_variables
|
39
|
+
|
40
|
+
# ...then we put the streams back.
|
41
|
+
$stderr = STDERR
|
42
|
+
$stdin = STDIN
|
43
|
+
$stdout = STDOUT
|
44
|
+
end
|
45
|
+
|
46
|
+
# Proxy our exit code back to the injected kernel.
|
47
|
+
@kernel.exit(exit_code)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/gitall/version.rb
CHANGED
File without changes
|
data/lib/gitall.rb
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
# 3rd party + Internal
|
2
|
+
require 'pry'
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'json'
|
5
|
+
require 'cinch'
|
6
|
+
require 'cinch/plugins/basic_ctcp'
|
7
|
+
require 'cinch/plugins/identify'
|
8
|
+
require 'ostruct'
|
9
|
+
require 'recursive-open-struct'
|
10
|
+
require 'yaml'
|
11
|
+
require 'unirest'
|
12
|
+
require 'base64'
|
13
|
+
require 'active_support/all'
|
14
|
+
|
15
|
+
# Self
|
16
|
+
require 'gitall/logger'
|
17
|
+
require 'gitall/version'
|
18
|
+
|
19
|
+
# Parsers
|
20
|
+
#
|
21
|
+
require 'gitall/parsers/github'
|
22
|
+
require 'gitall/parsers/gitlab'
|
23
|
+
|
24
|
+
# Plugins
|
25
|
+
#
|
26
|
+
require 'gitall/plugins/admin'
|
27
|
+
require 'gitall/plugins/chancontrol'
|
28
|
+
require 'gitall/plugins/git'
|
29
|
+
require 'gitall/plugins/eval'
|
30
|
+
|
31
|
+
module GitAll
|
32
|
+
CFG = YAML.load_file(Pathname(Dir.home).join('.gitall-rc.yml'))
|
33
|
+
USERS = CFG['users']
|
34
|
+
PROJECTS = CFG['projects']
|
35
|
+
# Houses all the gitall bots and their data
|
36
|
+
class Bot
|
37
|
+
class Users
|
38
|
+
attr :users
|
39
|
+
@users = []
|
40
|
+
|
41
|
+
class User < Struct.new :nickname, :password, :type
|
42
|
+
def authenticate(pass)
|
43
|
+
password == pass
|
44
|
+
end
|
45
|
+
end
|
46
|
+
GitAll::USERS.each do |user, hash|
|
47
|
+
password = hash['password']
|
48
|
+
role = hash['role']
|
49
|
+
@users << User.new(user, password, role)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
class Bots
|
53
|
+
attr :bots, :config
|
54
|
+
|
55
|
+
@bots = {}
|
56
|
+
@config = GitAll::CFG
|
57
|
+
|
58
|
+
def self.bots
|
59
|
+
@bots
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.add_bots
|
63
|
+
@config['networks'].each do |name, ncfg|
|
64
|
+
bot = Cinch::Bot.new do
|
65
|
+
configure do |c|
|
66
|
+
c.server = ncfg.fetch('server')
|
67
|
+
c.port = ncfg.fetch('port')
|
68
|
+
c.nick = ncfg.fetch('nickname')
|
69
|
+
c.user = ncfg.fetch('username')
|
70
|
+
c.realname = ncfg.fetch('realname')
|
71
|
+
c.plugins.prefix = Regexp.new(ncfg.fetch('prefix'))
|
72
|
+
c.plugins.plugins << Cinch::Plugins::Identify
|
73
|
+
identify_with = ncfg.fetch('identify-with')
|
74
|
+
case identify_with
|
75
|
+
when 'nickserv'
|
76
|
+
begin
|
77
|
+
c.plugins.options[Cinch::Plugins::Identify] = {
|
78
|
+
:username => ncfg.fetch('sasl-username'),
|
79
|
+
:password => ncfg.fetch('sasl-password'),
|
80
|
+
:type => :nickserv,
|
81
|
+
}
|
82
|
+
rescue KeyError
|
83
|
+
# ignored
|
84
|
+
end
|
85
|
+
when 'sasl'
|
86
|
+
begin
|
87
|
+
c.sasl.username = ncfg.fetch('sasl-username')
|
88
|
+
c.sasl.password = ncfg.fetch('sasl-password')
|
89
|
+
rescue KeyError
|
90
|
+
# ignored
|
91
|
+
end
|
92
|
+
when 'cert'
|
93
|
+
begin
|
94
|
+
c.ssl.client_cert = ncfg.fetch('certfp')
|
95
|
+
rescue KeyError
|
96
|
+
# ignored
|
97
|
+
end
|
98
|
+
when 'none'
|
99
|
+
# Don't identify
|
100
|
+
else
|
101
|
+
# noop
|
102
|
+
end
|
103
|
+
c.channels = ncfg.fetch('channels')
|
104
|
+
c.ssl.use = ncfg.fetch('ssl')
|
105
|
+
c.ssl.verify = ncfg.fetch('sslverify')
|
106
|
+
c.messages_per_second = ncfg.fetch('mps')
|
107
|
+
# Global configuration. This means that all plugins / matchers that
|
108
|
+
# implement authentication make use of the :login strategy, with a user
|
109
|
+
# level of :users.
|
110
|
+
c.authentication = Cinch::Configuration::Authentication.new
|
111
|
+
c.authentication.strategy = :login
|
112
|
+
c.authentication.level = :users
|
113
|
+
# The UserLogin plugin will call this lambda when a user runs !register.
|
114
|
+
#c.authentication.registration = lambda { |nickname, password|
|
115
|
+
# If you were using an ORM, you'd do something like
|
116
|
+
# `User.create(:nickname => nickname, :password => password)` here.
|
117
|
+
# return false if Users.users.one? { |user| user.nickname == nickname }
|
118
|
+
# Users.users << User.new(nickname, password, 'user')
|
119
|
+
#}
|
120
|
+
# The UserLogin plugin will call this lambda when a user runs !login. Note:
|
121
|
+
# the class it returns must respond to #authenticate with 1 argument (the
|
122
|
+
# password the user tries to login with).
|
123
|
+
c.authentication.fetch_user = lambda { |nickname|
|
124
|
+
# If you were using an ORM, you'd probably do something like
|
125
|
+
# `User.first(:nickname => nickname)` here.
|
126
|
+
Users.users.find { |user| user.nickname == nickname } }
|
127
|
+
# The Authentication mixin will call these lambdas to check if a user is
|
128
|
+
# allowed to run a command.
|
129
|
+
c.authentication.users = lambda { |user| user.type == 'user' }
|
130
|
+
c.authentication.admins = lambda { |user| user.type == 'admin' }
|
131
|
+
c.plugins.plugins << Cinch::Plugins::UserLogin
|
132
|
+
c.plugins.plugins << Cinch::Plugins::BasicCTCP
|
133
|
+
c.plugins.options[Cinch::Plugins::BasicCTCP][:replies] = {
|
134
|
+
version: "GitAll Version: v#{GitAll::VERSION}",
|
135
|
+
source: 'https://gitlab.com/gitall/gitall'
|
136
|
+
}
|
137
|
+
c.plugins.plugins << ChanControl
|
138
|
+
c.plugins.options[ChanControl][:authentication_level] = :admins
|
139
|
+
c.plugins.plugins << Admin
|
140
|
+
c.plugins.options[Admin][:authentication_level] = :admins
|
141
|
+
c.plugins.plugins << Eval
|
142
|
+
c.plugins.options[Eval][:authentication_level] = :admins
|
143
|
+
c.plugins.plugins << Cinch::Plugins::UserList
|
144
|
+
c.plugins.options[Cinch::Plugins::UserList][:authentication_level] = :admins
|
145
|
+
end
|
146
|
+
end
|
147
|
+
bot.loggers.clear
|
148
|
+
unless Pathname(Dir.home).join('.girc', 'log', "gitall-#{name}.log").exist?
|
149
|
+
FileUtils.mkdir_p(Pathname(Dir.home).join('.girc', 'log').to_path)
|
150
|
+
end
|
151
|
+
bot.loggers << GitLogger.new(name, File.open(Pathname(Dir.home).join(".girc", "log", "gitall-#{name}.log"), 'a'))
|
152
|
+
bot.loggers << GitLogger.new(name, STDOUT)
|
153
|
+
bot.loggers.level = :debug
|
154
|
+
@bots[name] = bot
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
class WebHook < Sinatra::Base
|
161
|
+
set :port, 8008
|
162
|
+
set :bind, '127.0.0.1'
|
163
|
+
set :environment, 'production'
|
164
|
+
#set :threaded, true
|
165
|
+
post '/hook/?' do
|
166
|
+
request.body.rewind
|
167
|
+
payload = request.body.read
|
168
|
+
json = JSON.load(payload)
|
169
|
+
j = RecursiveOpenStruct.new(json)
|
170
|
+
repo = ''
|
171
|
+
if request.env.key? 'HTTP_X_GITLAB_TOKEN'
|
172
|
+
repo = j.project.path_with_namespace
|
173
|
+
resp = GitLabParser.parse json
|
174
|
+
phash = PROJECTS[repo]
|
175
|
+
if phash['token'] == request.env['HTTP_X_GITLAB_TOKEN']
|
176
|
+
channels = phash['channels']
|
177
|
+
channels.each do |channet|
|
178
|
+
channel = channet.split(',')[0]
|
179
|
+
net = channet.split(',')[1]
|
180
|
+
resp.each do |n|
|
181
|
+
Bots.bots[net].Channel(channel).send("#{n}")
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
elsif request.env.key? 'HTTP_X_HUB_SIGNATURE'
|
186
|
+
if !j.repository.full_name.nil?
|
187
|
+
repo = j.repository.full_name
|
188
|
+
elsif !j.organization.login.nil?
|
189
|
+
repo = j.organization.login
|
190
|
+
else
|
191
|
+
end
|
192
|
+
# phash includes orgs and repos
|
193
|
+
phash = PROJECTS[repo.to_sym]
|
194
|
+
token = phash['token']
|
195
|
+
sent_token = request.env['HTTP_X_HUB_SIGNATURE']
|
196
|
+
signature = "sha1=#{OpenSSL::HMAC.hexdigest('sha1', token, payload.strip).chomp}"
|
197
|
+
resp = GitHubParser.parse json, request.env['HTTP_X_GITHUB_EVENT']
|
198
|
+
if signature.to_s == sent_token.to_s
|
199
|
+
channels = phash['channels'.to_sym]
|
200
|
+
channels.each {
|
201
|
+
|channet|
|
202
|
+
channel = channet.split(',')[0]
|
203
|
+
network = channet.split(',')[1]
|
204
|
+
resp.each {
|
205
|
+
|n|
|
206
|
+
GitAll::Bots.bots[network].Channel(channel).send("#{n}")
|
207
|
+
}
|
208
|
+
}
|
209
|
+
end
|
210
|
+
|
211
|
+
elsif request.env.key?('HTTP_X_GOGS_EVENT')
|
212
|
+
|
213
|
+
elsif request.env.key?('HTTP_X_EVENT_KEY')
|
214
|
+
# BitBucket's Webhooks
|
215
|
+
# Requires HTTPS and does not
|
216
|
+
# implement a secret unless set into
|
217
|
+
# the url.
|
218
|
+
status 404
|
219
|
+
body 'bitbucket not implemented'
|
220
|
+
else
|
221
|
+
[404, "I can't help with that"]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitall
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Spencer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cinch
|
@@ -16,14 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.3
|
19
|
+
version: '2.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.3
|
26
|
+
version: '2.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: cinch-authentication
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.1.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cinch-identify
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: cinch-basic_ctcp
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.1'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.1'
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: sinatra
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -64,6 +106,62 @@ dependencies:
|
|
64
106
|
- - ">="
|
65
107
|
- !ruby/object:Gem::Version
|
66
108
|
version: 2.0.2
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: recursive-open-struct
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - "~>"
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '1.1'
|
116
|
+
type: :runtime
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '1.1'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: activesupport
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '5.2'
|
130
|
+
type: :runtime
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "~>"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '5.2'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: unirest
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '1.1'
|
144
|
+
type: :runtime
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - "~>"
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '1.1'
|
151
|
+
- !ruby/object:Gem::Dependency
|
152
|
+
name: strgen
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - "~>"
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0.1'
|
158
|
+
type: :runtime
|
159
|
+
prerelease: false
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - "~>"
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0.1'
|
67
165
|
- !ruby/object:Gem::Dependency
|
68
166
|
name: thor
|
69
167
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,9 +282,16 @@ executables:
|
|
184
282
|
extensions: []
|
185
283
|
extra_rdoc_files: []
|
186
284
|
files:
|
285
|
+
- ".gitignore"
|
286
|
+
- ".travis.yml"
|
287
|
+
- Gemfile
|
288
|
+
- README.md
|
187
289
|
- bin/gitall
|
188
|
-
-
|
189
|
-
-
|
290
|
+
- example.gitall-rc.yml
|
291
|
+
- gitall.gemspec
|
292
|
+
- lib/gitall.rb
|
293
|
+
- lib/gitall/cli/app.rb
|
294
|
+
- lib/gitall/cli/runner.rb
|
190
295
|
- lib/gitall/logger.rb
|
191
296
|
- lib/gitall/parsers/bitbucket.rb
|
192
297
|
- lib/gitall/parsers/github.rb
|
@@ -196,8 +301,8 @@ files:
|
|
196
301
|
- lib/gitall/plugins/eval.rb
|
197
302
|
- lib/gitall/plugins/git.rb
|
198
303
|
- lib/gitall/version.rb
|
199
|
-
- lib/views/_403.erb
|
200
|
-
homepage: https://
|
304
|
+
- lib/gitall/views/_403.erb
|
305
|
+
homepage: https://iotaspencer.me/projects/gitall
|
201
306
|
licenses:
|
202
307
|
- MIT
|
203
308
|
metadata: {}
|
data/lib/cli/app.rb
DELETED
File without changes
|
data/lib/gitall/gitall.rb
DELETED
@@ -1,200 +0,0 @@
|
|
1
|
-
require 'recursive_open_struct'
|
2
|
-
require 'json'
|
3
|
-
|
4
|
-
require 'parsers/github'
|
5
|
-
require 'parsers/gitlab'
|
6
|
-
|
7
|
-
require 'plugins/admin'
|
8
|
-
require 'plugins/chancontrol'
|
9
|
-
require 'plugins/git'
|
10
|
-
require 'plugins/eval'
|
11
|
-
|
12
|
-
module GitAll
|
13
|
-
CFG = File.open(Pathname(Dir.home).join('gitall-rc.yml'), 'r').read
|
14
|
-
USERS = CFG['users']
|
15
|
-
PROJECTS = CFG['projects']
|
16
|
-
# Houses all the gitall bots and their data
|
17
|
-
|
18
|
-
class Users
|
19
|
-
attr :users
|
20
|
-
@users = []
|
21
|
-
|
22
|
-
class User < Struct.new :nickname, :password, :type
|
23
|
-
def authenticate(pass)
|
24
|
-
password == pass
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
USERS.each do |user, hash|
|
29
|
-
password = hash['password']
|
30
|
-
role = hash['role']
|
31
|
-
@users << User.new(user, password, role)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
class Bots
|
35
|
-
attr :bots, :config
|
36
|
-
|
37
|
-
@bots = {}
|
38
|
-
@config = GitAll::CFG
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
def add_bots
|
43
|
-
@config['networks'].each do |name, ncfg|
|
44
|
-
bot = Cinch::Bot.new do
|
45
|
-
configure do |c|
|
46
|
-
c.server = ncfg.fetch('server')
|
47
|
-
c.port = ncfg.fetch('port')
|
48
|
-
c.nick = ncfg.fetch('nickname')
|
49
|
-
c.user = ncfg.fetch('username')
|
50
|
-
c.realname = ncfg.fetch('realname')
|
51
|
-
c.plugins.prefix = Regexp.new(ncfg.fetch('prefix'))
|
52
|
-
c.plugins.plugins << Cinch::Plugins::Identify
|
53
|
-
identify_with = ncfg.fetch('identify-with')
|
54
|
-
case identify_with
|
55
|
-
when 'nickserv'
|
56
|
-
begin
|
57
|
-
c.plugins.options[Cinch::Plugins::Identify] = {
|
58
|
-
:username => ncfg.fetch('sasl-username'),
|
59
|
-
:password => ncfg.fetch('sasl-password'),
|
60
|
-
:type => :nickserv,
|
61
|
-
}
|
62
|
-
rescue KeyError
|
63
|
-
# ignored
|
64
|
-
end
|
65
|
-
when 'sasl'
|
66
|
-
begin
|
67
|
-
c.sasl.username = ncfg.fetch('sasl-username')
|
68
|
-
c.sasl.password = ncfg.fetch('sasl-password')
|
69
|
-
rescue KeyError
|
70
|
-
# ignored
|
71
|
-
end
|
72
|
-
when 'cert'
|
73
|
-
begin
|
74
|
-
c.ssl.client_cert = ncfg.fetch('certfp')
|
75
|
-
rescue KeyError
|
76
|
-
# ignored
|
77
|
-
end
|
78
|
-
when 'none'
|
79
|
-
# Don't identify
|
80
|
-
else
|
81
|
-
# noop
|
82
|
-
end
|
83
|
-
c.channels = ncfg.fetch('channels')
|
84
|
-
c.ssl.use = ncfg.fetch('ssl')
|
85
|
-
c.ssl.verify = ncfg.fetch('sslverify')
|
86
|
-
c.messages_per_second = ncfg.fetch('mps')
|
87
|
-
# Global configuration. This means that all plugins / matchers that
|
88
|
-
# implement authentication make use of the :login strategy, with a user
|
89
|
-
# level of :users.
|
90
|
-
c.authentication = Cinch::Configuration::Authentication.new
|
91
|
-
c.authentication.strategy = :login
|
92
|
-
c.authentication.level = :users
|
93
|
-
# The UserLogin plugin will call this lambda when a user runs !register.
|
94
|
-
#c.authentication.registration = lambda { |nickname, password|
|
95
|
-
# If you were using an ORM, you'd do something like
|
96
|
-
# `User.create(:nickname => nickname, :password => password)` here.
|
97
|
-
# return false if Users.users.one? { |user| user.nickname == nickname }
|
98
|
-
# Users.users << User.new(nickname, password, 'user')
|
99
|
-
#}
|
100
|
-
# The UserLogin plugin will call this lambda when a user runs !login. Note:
|
101
|
-
# the class it returns must respond to #authenticate with 1 argument (the
|
102
|
-
# password the user tries to login with).
|
103
|
-
c.authentication.fetch_user = lambda { |nickname|
|
104
|
-
# If you were using an ORM, you'd probably do something like
|
105
|
-
# `User.first(:nickname => nickname)` here.
|
106
|
-
Users.users.find { |user| user.nickname == nickname } }
|
107
|
-
# The Authentication mixin will call these lambdas to check if a user is
|
108
|
-
# allowed to run a command.
|
109
|
-
c.authentication.users = lambda { |user| user.type == 'user' }
|
110
|
-
c.authentication.admins = lambda { |user| user.type == 'admin' }
|
111
|
-
c.plugins.plugins << Cinch::Plugins::UserLogin
|
112
|
-
c.plugins.plugins << Cinch::Plugins::BasicCTCP
|
113
|
-
c.plugins.options[Cinch::Plugins::BasicCTCP][:replies] = {
|
114
|
-
version: Version::Bot.version,
|
115
|
-
source: 'https://gitlab.com/gitall/gitall'
|
116
|
-
}
|
117
|
-
c.plugins.plugins << ChanControl
|
118
|
-
c.plugins.options[ChanControl][:authentication_level] = :admins
|
119
|
-
c.plugins.plugins << Admin
|
120
|
-
c.plugins.options[Admin][:authentication_level] = :admins
|
121
|
-
c.plugins.plugins << Eval
|
122
|
-
c.plugins.options[Eval][:authentication_level] = :admins
|
123
|
-
c.plugins.plugins << Cinch::Plugins::UserList
|
124
|
-
c.plugins.options[Cinch::Plugins::UserList][:authentication_level] = :admins
|
125
|
-
end
|
126
|
-
end
|
127
|
-
bot.loggers.clear
|
128
|
-
bot.loggers << GitLogger.new(name, File.open("log/gitall-#{name}.log", 'a'))
|
129
|
-
bot.loggers << GitLogger.new(name, STDOUT)
|
130
|
-
bot.loggers.level = :debug
|
131
|
-
self.bots[name] = bot
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
135
|
-
class WebHook < Sinatra::Base
|
136
|
-
set :port, 8008
|
137
|
-
set :bind, '127.0.0.1'
|
138
|
-
set :environment, 'production'
|
139
|
-
set :threaded, true
|
140
|
-
post '/hook/?' do
|
141
|
-
request.body.rewind
|
142
|
-
payload = request.body.read
|
143
|
-
json = JSON.load(payload)
|
144
|
-
j = RecursiveOpenStruct.new(json)
|
145
|
-
repo = ''
|
146
|
-
if request.env.key? 'HTTP_X_GITLAB_TOKEN'
|
147
|
-
repo = j.project.path_with_namespace
|
148
|
-
resp = GitLabParser.parse json
|
149
|
-
phash = PROJECTS[repo]
|
150
|
-
if phash['token'] == request.env['HTTP_X_GITLAB_TOKEN']
|
151
|
-
channels = phash['channels']
|
152
|
-
channels.each do |channet|
|
153
|
-
channel = channet.split(',')[0]
|
154
|
-
net = channet.split(',')[1]
|
155
|
-
resp.each do |n|
|
156
|
-
Bots.bots[net].Channel(channel).send("#{n}")
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
elsif request.env.key? 'HTTP_X_HUB_SIGNATURE'
|
161
|
-
if !j.repository.full_name.nil?
|
162
|
-
repo = j.repository.full_name
|
163
|
-
elsif !j.organization.login.nil?
|
164
|
-
repo = j.organization.login
|
165
|
-
else
|
166
|
-
end
|
167
|
-
# phash includes orgs and repos
|
168
|
-
phash = PROJECTS[repo.to_sym]
|
169
|
-
token = phash['token']
|
170
|
-
sent_token = request.env['HTTP_X_HUB_SIGNATURE']
|
171
|
-
signature = "sha1=#{OpenSSL::HMAC.hexdigest('sha1', token, payload.strip).chomp}"
|
172
|
-
resp = GitHubParser.parse json, request.env['HTTP_X_GITHUB_EVENT']
|
173
|
-
if signature.to_s == sent_token.to_s
|
174
|
-
channels = phash['channels'.to_sym]
|
175
|
-
channels.each {
|
176
|
-
|channet|
|
177
|
-
channel = channet.split(',')[0]
|
178
|
-
network = channet.split(',')[1]
|
179
|
-
resp.each {
|
180
|
-
|n|
|
181
|
-
GitAll::Bots.bots[network].Channel(channel).send("#{n}")
|
182
|
-
}
|
183
|
-
}
|
184
|
-
end
|
185
|
-
|
186
|
-
elsif request.env.key?('HTTP_X_GOGS_EVENT')
|
187
|
-
|
188
|
-
elsif request.env.key?('HTTP_X_EVENT_KEY')
|
189
|
-
# BitBucket's Webhooks
|
190
|
-
# Requires HTTPS and does not
|
191
|
-
# implement a secret unless set into
|
192
|
-
# the url.
|
193
|
-
status 404
|
194
|
-
body 'bitbucket not implemented'
|
195
|
-
else
|
196
|
-
[404, "I can't help with that"]
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
end
|