add-to-org 2.2.0 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.bowerrc +3 -0
- data/.github/workflows/ci.yml +24 -0
- data/.gitignore +7 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +100 -0
- data/Gemfile +3 -1
- data/README.md +68 -25
- data/Rakefile +5 -3
- data/add-to-org.gemspec +24 -21
- data/bower.json +13 -0
- data/lib/add-to-org/helpers.rb +16 -13
- data/lib/add-to-org/version.rb +3 -1
- data/lib/add-to-org/views/error.erb +5 -12
- data/lib/add-to-org/views/forbidden.erb +5 -12
- data/lib/add-to-org/views/layout.erb +16 -0
- data/lib/add-to-org/views/success.erb +5 -12
- data/lib/add-to-org.rb +47 -13
- data/script/cibuild +1 -0
- data/spec/add-to-org-helpers_spec.rb +48 -40
- data/spec/add-to-org_spec.rb +102 -69
- data/spec/spec_helper.rb +16 -12
- metadata +76 -44
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d6e1d519910bd9dae03bcb2c8cea47fcebb6fb188c48d7103dfec6e1a40df664
|
4
|
+
data.tar.gz: 5ef8eb34932716326573c30beb922c55b2549bf5cb2d0ce2cd273ddd8ef409b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 336633b4e2062a6e8de5411bf38ae7cab6b085a626b7af679f83a880d5781d3713933df4bf5434d2b3f09b532dafe177364f88e02274fd2c8657540acfa7b983
|
7
|
+
data.tar.gz: 4b41e21b69c44f9109b47ba0408dc6ff63400d481bbc5738be4a035c35a0597a1e41d0d2045942749dba06fcf769d8e01561a6908a7b0009666f8e0cff6ce5b6
|
data/.bowerrc
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [master]
|
6
|
+
pull_request:
|
7
|
+
branches: [master]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- name: Checkout
|
15
|
+
uses: actions/checkout@v2
|
16
|
+
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: 3.0
|
21
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
22
|
+
|
23
|
+
- name: Run tests
|
24
|
+
run: script/cibuild
|
data/.gitignore
CHANGED
@@ -2,3 +2,10 @@
|
|
2
2
|
.bundle
|
3
3
|
*.gem
|
4
4
|
Gemfile.lock
|
5
|
+
/lib/add-to-org/public/vendor/jquery
|
6
|
+
/lib/add-to-org/public/vendor/bootstrap/grunt
|
7
|
+
/lib/add-to-org/public/vendor/bootstrap/js
|
8
|
+
/lib/add-to-org/public/vendor/bootstrap/less
|
9
|
+
/lib/add-to-org/public/vendor/bootstrap/nuget
|
10
|
+
/lib/add-to-org/public/vendor/bootstrap/*.md
|
11
|
+
/lib/add-to-org/public/vendor/bootstrap/*.js
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2021-10-07 20:24:39 UTC using RuboCop version 1.22.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 1
|
10
|
+
# Configuration parameters: Include.
|
11
|
+
# Include: **/*.gemspec
|
12
|
+
Gemspec/RequiredRubyVersion:
|
13
|
+
Exclude:
|
14
|
+
- 'add-to-org.gemspec'
|
15
|
+
|
16
|
+
# Offense count: 3
|
17
|
+
# Configuration parameters: IgnoredMethods.
|
18
|
+
Lint/AmbiguousBlockAssociation:
|
19
|
+
Exclude:
|
20
|
+
- 'lib/add-to-org.rb'
|
21
|
+
|
22
|
+
# Offense count: 1
|
23
|
+
# Configuration parameters: AllowedMethods.
|
24
|
+
# AllowedMethods: enums
|
25
|
+
Lint/ConstantDefinitionInBlock:
|
26
|
+
Exclude:
|
27
|
+
- 'spec/add-to-org-helpers_spec.rb'
|
28
|
+
|
29
|
+
# Offense count: 4
|
30
|
+
# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
|
31
|
+
# IgnoredMethods: refine
|
32
|
+
Metrics/BlockLength:
|
33
|
+
Max: 88
|
34
|
+
|
35
|
+
# Offense count: 1
|
36
|
+
Naming/AccessorMethodName:
|
37
|
+
Exclude:
|
38
|
+
- 'lib/add-to-org.rb'
|
39
|
+
|
40
|
+
# Offense count: 3
|
41
|
+
# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, Regex, IgnoreExecutableScripts, AllowedAcronyms.
|
42
|
+
# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
|
43
|
+
Naming/FileName:
|
44
|
+
Exclude:
|
45
|
+
- 'lib/add-to-org.rb'
|
46
|
+
- 'spec/add-to-org-helpers_spec.rb'
|
47
|
+
- 'spec/add-to-org_spec.rb'
|
48
|
+
|
49
|
+
# Offense count: 3
|
50
|
+
# Configuration parameters: IgnoredMetadata.
|
51
|
+
RSpec/DescribeClass:
|
52
|
+
Exclude:
|
53
|
+
- '**/spec/features/**/*'
|
54
|
+
- '**/spec/requests/**/*'
|
55
|
+
- '**/spec/routing/**/*'
|
56
|
+
- '**/spec/system/**/*'
|
57
|
+
- '**/spec/views/**/*'
|
58
|
+
- 'spec/add-to-org_spec.rb'
|
59
|
+
|
60
|
+
# Offense count: 6
|
61
|
+
# Configuration parameters: CountAsOne.
|
62
|
+
RSpec/ExampleLength:
|
63
|
+
Max: 16
|
64
|
+
|
65
|
+
# Offense count: 14
|
66
|
+
# Configuration parameters: AssignmentOnly.
|
67
|
+
RSpec/InstanceVariable:
|
68
|
+
Exclude:
|
69
|
+
- 'spec/add-to-org-helpers_spec.rb'
|
70
|
+
- 'spec/add-to-org_spec.rb'
|
71
|
+
|
72
|
+
# Offense count: 1
|
73
|
+
RSpec/LeakyConstantDeclaration:
|
74
|
+
Exclude:
|
75
|
+
- 'spec/add-to-org-helpers_spec.rb'
|
76
|
+
|
77
|
+
# Offense count: 1
|
78
|
+
RSpec/MultipleDescribes:
|
79
|
+
Exclude:
|
80
|
+
- 'spec/add-to-org_spec.rb'
|
81
|
+
|
82
|
+
# Offense count: 9
|
83
|
+
RSpec/MultipleExpectations:
|
84
|
+
Max: 6
|
85
|
+
|
86
|
+
# Offense count: 3
|
87
|
+
# Configuration parameters: AllowedConstants.
|
88
|
+
Style/Documentation:
|
89
|
+
Exclude:
|
90
|
+
- 'spec/**/*'
|
91
|
+
- 'test/**/*'
|
92
|
+
- 'lib/add-to-org.rb'
|
93
|
+
- 'lib/add-to-org/helpers.rb'
|
94
|
+
|
95
|
+
# Offense count: 1
|
96
|
+
# Cop supports --auto-correct.
|
97
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
98
|
+
# URISchemes: http, https
|
99
|
+
Layout/LineLength:
|
100
|
+
Max: 124
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,10 +10,35 @@ Once set up, simply swap out your app's domain for any GitHub URL. E.g., `github
|
|
10
10
|
|
11
11
|
## Setup
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
*Pro-tip: for a quickstart on how to set up the app, see the [add-to-org demo app](https://github.com/benbalter/add-to-org-demo).*
|
14
|
+
|
15
|
+
### Credentials
|
16
|
+
|
17
|
+
You'll need a few different credentials for things to work:
|
18
|
+
|
19
|
+
#### A bot account
|
20
|
+
|
21
|
+
You'll need a dedicated "bot" account to add users to the organization:
|
22
|
+
|
23
|
+
1. [Create a bot account](https://github.com/signup) (a standard GitHub account not used by a human) that has *admin* rights to your organization.
|
24
|
+
2. [Create a personal access token](https://github.com/settings/tokens/new) for that user, with `admin:org` scope.
|
25
|
+
|
26
|
+
#### An OAuth application
|
27
|
+
|
28
|
+
You'll also need to create an OAUth application to validate users:
|
29
|
+
|
30
|
+
1. Create an OAauth application *within your organization* via `https://github.com/organizations/[YOUR-ORGANIZATION-NAME]/settings/applications/new`
|
31
|
+
2. The homepage URL should be the URL to your production instance.
|
32
|
+
3. You can leave the callback URL blank. The default is fine.
|
33
|
+
|
34
|
+
## Developing locally and deploying
|
35
|
+
|
36
|
+
*Pro-tip: for a quickstart on how to set up the app, see the [add-to-org demo app](https://github.com/benbalter/add-to-org-demo)*
|
37
|
+
|
38
|
+
1. Create [an oauth app](github.com/settings/applications/new) (see above)
|
39
|
+
2. Create a personal access token for a user with admin rights to the organization (see above)
|
15
40
|
3. Add `gem 'add-to-org' to your project's Gemfile
|
16
|
-
4. Add the following to
|
41
|
+
4. Add the following to your project's `config.ru` file:
|
17
42
|
|
18
43
|
```ruby
|
19
44
|
require 'add-to-org'
|
@@ -31,40 +56,58 @@ The following environmental values should be set:
|
|
31
56
|
* `GITHUB_TOKEN` - A personal access token for a user with admin rights to the organization
|
32
57
|
* `CONTACT_EMAIL` - Point of contact to point users to if something goes wrong
|
33
58
|
|
34
|
-
|
59
|
+
### Customizing the validator
|
60
|
+
|
61
|
+
For Add to Org to work, you'll also need to define a custom validator. You can do this in your `configu.ru`, or in a separate file included into `config.ru`. Here's an example of a validator that confirms the user has a verified `@github.com` email address:
|
35
62
|
|
36
63
|
```ruby
|
37
64
|
require 'add-to-org'
|
38
65
|
|
39
|
-
|
40
|
-
|
41
|
-
def valid?
|
42
|
-
verified_emails.any? { |email| email[:email] =~ /@github\.com$/}
|
43
|
-
end
|
44
|
-
end
|
66
|
+
AddToOrg.set_validator do |github_user, verified_emails, client|
|
67
|
+
verified_emails.any? { |email| email[:email] =~ /@github\.com\z/ }
|
45
68
|
end
|
69
|
+
|
70
|
+
run AddToOrg::App
|
46
71
|
```
|
47
72
|
|
48
|
-
|
73
|
+
If you prefer, you can also pass the validator as a proc (or lambda):
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
AddToOrg.validator = proc { |github_user, verified_emails, client|
|
77
|
+
verified_emails.any? { |email| email[:email] =~ /@github\.com\z/ }
|
78
|
+
}
|
79
|
+
```
|
49
80
|
|
50
|
-
|
81
|
+
The validator will receive three arguments to help you validate the user meets your criteria:
|
82
|
+
|
83
|
+
* `github_user` - the Warden user, which will contain information like username, company, and human-readable name
|
84
|
+
* `verified_emails` - an array of the user's verified emails
|
85
|
+
* `client` - An [Octokit.rb](https://github.com/octokit/octokit.rb) client, preset with the user's OAuth token.
|
86
|
+
|
87
|
+
The validator should return `true` if you'd like the current user added to the organization, or `false` if you'd like the user's request to be denied.
|
88
|
+
|
89
|
+
### Customizing Views
|
90
|
+
|
91
|
+
There are three views, `success`, `forbidden`, and `error`. They're pretty boring by default, so you may want to swap them out for something a bit my snazzy. If you had a views directory along side your `config.ru`, you can do so like this in your `config.ru` file:
|
51
92
|
|
52
93
|
```ruby
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
94
|
+
require 'add-to-org'
|
95
|
+
|
96
|
+
AddToOrgs.views_dir = File.expand_path("./views", File.dirname(__FILE__))
|
97
|
+
|
98
|
+
run AddToOrg::App
|
58
99
|
```
|
59
100
|
|
60
|
-
|
101
|
+
These are just sinatra `.erb` views. Take a look at [the default views](https://github.com/benbalter/add-to-org/tree/master/lib/add-to-org/views) for an example.
|
102
|
+
|
103
|
+
### Customizing static assets
|
104
|
+
|
105
|
+
You can also do the same with `AddToOrg.public_dir` for serving static assets (AddToOrg comes bundled with Bootstrap by default).
|
61
106
|
|
62
107
|
```ruby
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
69
|
-
end
|
108
|
+
require 'add-to-org'
|
109
|
+
|
110
|
+
AddToOrgs.public_dir = File.expand_path("./public", File.dirname(__FILE__))
|
111
|
+
|
112
|
+
run AddToOrg::App
|
70
113
|
```
|
data/Rakefile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rubygems/package_task'
|
2
4
|
require 'rubygems/specification'
|
3
5
|
require 'bundler'
|
4
6
|
|
5
|
-
task :
|
7
|
+
task default: [:spec]
|
6
8
|
|
7
9
|
require 'rspec/core/rake_task'
|
8
|
-
desc
|
10
|
+
desc 'Run specs'
|
9
11
|
RSpec::Core::RakeTask.new do |t|
|
10
12
|
t.pattern = 'spec/**/*_spec.rb'
|
11
|
-
t.rspec_opts = [
|
13
|
+
t.rspec_opts = ['--order', 'rand', '--color']
|
12
14
|
end
|
data/add-to-org.gemspec
CHANGED
@@ -1,29 +1,32 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('lib/add-to-org/version', __dir__)
|
2
4
|
|
3
5
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
5
|
-
s.summary =
|
6
|
-
s.description =
|
6
|
+
s.name = 'add-to-org'
|
7
|
+
s.summary = 'A simple Oauth App to automatically add users to an organization'
|
8
|
+
s.description = 'A simple Oauth App to automatically add users to an organization.'
|
7
9
|
s.version = AddToOrg::VERSION
|
8
|
-
s.authors = [
|
9
|
-
s.email =
|
10
|
-
s.homepage =
|
11
|
-
s.licenses = [
|
10
|
+
s.authors = ['Ben Balter']
|
11
|
+
s.email = 'ben.balter@github.com'
|
12
|
+
s.homepage = 'https://github.com/benbalter/add-to-org'
|
13
|
+
s.licenses = ['MIT']
|
12
14
|
|
13
15
|
s.files = `git ls-files`.split("\n")
|
14
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
-
s.require_paths = [
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
18
|
+
s.require_paths = ['lib']
|
17
19
|
|
18
|
-
s.
|
19
|
-
s.add_dependency
|
20
|
-
s.add_dependency
|
21
|
-
s.add_dependency
|
22
|
-
s.add_dependency
|
23
|
-
s.
|
24
|
-
s.
|
25
|
-
s.add_development_dependency
|
26
|
-
s.add_development_dependency
|
27
|
-
s.add_development_dependency
|
28
|
-
s.add_development_dependency
|
20
|
+
s.add_dependency 'dotenv', '~> 2.0'
|
21
|
+
s.add_dependency 'octokit', '~> 4.0'
|
22
|
+
s.add_dependency 'rack-ssl-enforcer', '~> 0.2'
|
23
|
+
s.add_dependency 'rake'
|
24
|
+
s.add_dependency 'sinatra_auth_github', '~> 2.0'
|
25
|
+
s.add_development_dependency 'pry'
|
26
|
+
s.add_development_dependency 'rack-test'
|
27
|
+
s.add_development_dependency 'rspec', '~> 3.1'
|
28
|
+
s.add_development_dependency 'rubocop'
|
29
|
+
s.add_development_dependency 'rubocop-performance'
|
30
|
+
s.add_development_dependency 'rubocop-rspec'
|
31
|
+
s.add_development_dependency 'webmock'
|
29
32
|
end
|
data/bower.json
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"name": "add-to-org",
|
3
|
+
"homepage": "https://github.com/benbalter/add-to-org",
|
4
|
+
"authors": [
|
5
|
+
"Ben Balter <ben.balter@github.com>"
|
6
|
+
],
|
7
|
+
"description": "A simple Oauth App to automatically add users to an organization",
|
8
|
+
"main": "script/server",
|
9
|
+
"moduleType": [],
|
10
|
+
"license": "MIT",
|
11
|
+
"private": true,
|
12
|
+
"dependencies": {}
|
13
|
+
}
|
data/lib/add-to-org/helpers.rb
CHANGED
@@ -1,20 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module AddToOrg
|
2
4
|
module Helpers
|
5
|
+
# query api for the user's verified emails
|
6
|
+
def verified_emails
|
7
|
+
emails = client.emails accept: 'application/vnd.github.v3'
|
8
|
+
emails.select(&:verified)
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid?
|
12
|
+
AddToOrg.validator.call(github_user, verified_emails, client)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
3
16
|
|
4
17
|
# user client
|
5
18
|
def client
|
6
|
-
@client ||= Octokit::Client.new :
|
19
|
+
@client ||= Octokit::Client.new access_token: github_user.token
|
7
20
|
end
|
8
21
|
|
9
|
-
#
|
22
|
+
# org admin client
|
10
23
|
def sudo_client
|
11
|
-
@sudo_client ||= Octokit::Client.new :
|
12
|
-
end
|
13
|
-
|
14
|
-
# query api for the user's verified emails
|
15
|
-
def verified_emails
|
16
|
-
emails = client.emails :accept => 'application/vnd.github.v3'
|
17
|
-
emails.select { |email| email.verified }
|
24
|
+
@sudo_client ||= Octokit::Client.new access_token: ENV['GITHUB_TOKEN']
|
18
25
|
end
|
19
26
|
|
20
27
|
# true if user is already a member of the org
|
@@ -22,10 +29,6 @@ module AddToOrg
|
|
22
29
|
client.organization_member? org_id, github_user.login
|
23
30
|
end
|
24
31
|
|
25
|
-
def valid?
|
26
|
-
raise "You must define a custom valid? method to determine eligibility"
|
27
|
-
end
|
28
|
-
|
29
32
|
def team_id
|
30
33
|
ENV['GITHUB_TEAM_ID']
|
31
34
|
end
|
data/lib/add-to-org/version.rb
CHANGED
@@ -1,12 +1,5 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</head>
|
7
|
-
<body>
|
8
|
-
<h1>Ruh roh</h1>
|
9
|
-
<p>Looks like something went wrong.</p>
|
10
|
-
<p>Please contact <a href="mailto:<%= ENV['CONTACT_EMAIL'] %>"><%= ENV['CONTACT_EMAIL'] %></a>.</p>
|
11
|
-
</body>
|
12
|
-
</html>
|
1
|
+
<h1>Ruh roh</h1>
|
2
|
+
|
3
|
+
<p>Looks like something went wrong.</p>
|
4
|
+
|
5
|
+
<p>Please contact <a href="mailto:<%= ENV['CONTACT_EMAIL'] %>"><%= ENV['CONTACT_EMAIL'] %></a>.</p>
|
@@ -1,12 +1,5 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</head>
|
7
|
-
<body>
|
8
|
-
<h1>Sorry Charlie</h1>
|
9
|
-
<p>We're unable to verify your eligibility at this time.</p>
|
10
|
-
<p>Please contact <a href="mailto:<%= ENV['CONTACT_EMAIL'] %>"><%= ENV['CONTACT_EMAIL'] %></a> if you believe this is in error.</p>
|
11
|
-
</body>
|
12
|
-
</html>
|
1
|
+
<h1>Sorry Charlie</h1>
|
2
|
+
|
3
|
+
<p>We're unable to verify your eligibility at this time.</p>
|
4
|
+
|
5
|
+
<p>Please contact <a href="mailto:<%= ENV['CONTACT_EMAIL'] %>"><%= ENV['CONTACT_EMAIL'] %></a> if you believe this is in error.</p>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>Join <%= ENV['GITHUB_ORG_ID'] %></title>
|
7
|
+
<style>
|
8
|
+
body { text-align: center; padding-top: 100px; }
|
9
|
+
</style>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div class="container">
|
13
|
+
<%= yield %>
|
14
|
+
</div>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -1,12 +1,5 @@
|
|
1
|
-
<
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</head>
|
7
|
-
<body>
|
8
|
-
<h1>You're all set</h1>
|
9
|
-
<p class="lead">You simply need to <a href="https://github.com/orgs/<%= @org_id %>/invitation?return_to=<%= ERB::Util.html_escape(redirect) %>">confirm your invitation to join the organization</a> on GitHub.</p>
|
10
|
-
<p>Once confirmed, you will have access to <a href="<%= ERB::Util.html_escape(redirect) %>"><%= ERB::Util.html_escape(redirect) %></a>, the requested URL.</h1>
|
11
|
-
</body>
|
12
|
-
</html>
|
1
|
+
<h1>You're all set</h1>
|
2
|
+
|
3
|
+
<p class="lead">You simply need to <a href="https://github.com/orgs/<%= org_id %>/invitation?return_to=<%= ERB::Util.html_escape(redirect) %>">confirm your invitation to join the organization</a> on GitHub.</p>
|
4
|
+
|
5
|
+
<p>Once confirmed, you will have access to <a href="<%= ERB::Util.html_escape(redirect) %>"><%= ERB::Util.html_escape(redirect) %></a>, the requested URL.</h1>
|
data/lib/add-to-org.rb
CHANGED
@@ -1,28 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'octokit'
|
2
4
|
require 'sinatra_auth_github'
|
3
5
|
require 'dotenv'
|
4
6
|
require_relative 'add-to-org/helpers'
|
5
7
|
|
6
|
-
Dotenv.load
|
7
|
-
|
8
8
|
module AddToOrg
|
9
|
-
|
9
|
+
def self.root
|
10
|
+
File.expand_path './add-to-org', File.dirname(__FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.views_dir
|
14
|
+
@views_dir ||= File.expand_path 'views', AddToOrg.root
|
15
|
+
end
|
10
16
|
|
17
|
+
def self.views_dir=(dir)
|
18
|
+
@views_dir = dir
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.public_dir
|
22
|
+
@public_dir ||= File.expand_path 'public', AddToOrg.root
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.public_dir=(dir)
|
26
|
+
@public_dir = dir
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.validator=(validator)
|
30
|
+
@validator = validator
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.set_validator(&block)
|
34
|
+
@validator = block
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.validator
|
38
|
+
@validator ||= proc { raise 'You must define a custom validator to determine eligibility' }
|
39
|
+
end
|
40
|
+
|
41
|
+
class App < Sinatra::Base
|
11
42
|
include AddToOrg::Helpers
|
12
43
|
|
13
44
|
set :github_options, {
|
14
|
-
:
|
45
|
+
scopes: 'read:org,user:email'
|
15
46
|
}
|
16
47
|
|
17
48
|
use Rack::Session::Cookie, {
|
18
|
-
:
|
19
|
-
:
|
49
|
+
http_only: true,
|
50
|
+
secret: ENV['SESSION_SECRET'] || SecureRandom.hex
|
20
51
|
}
|
21
52
|
|
22
53
|
ENV['WARDEN_GITHUB_VERIFIER_SECRET'] ||= SecureRandom.hex
|
23
54
|
register Sinatra::Auth::Github
|
24
55
|
|
25
|
-
set :views,
|
56
|
+
set :views, proc { AddToOrg.views_dir }
|
57
|
+
set :root, proc { AddToOrg.root }
|
58
|
+
set :public_folder, proc { AddToOrg.public_dir }
|
26
59
|
|
27
60
|
# require ssl
|
28
61
|
configure :production do
|
@@ -32,12 +65,12 @@ module AddToOrg
|
|
32
65
|
|
33
66
|
# dat auth
|
34
67
|
before do
|
35
|
-
session[:return_to] = request.url #store requested URL for post-auth redirect
|
68
|
+
session[:return_to] = request.url # store requested URL for post-auth redirect
|
36
69
|
authenticate!
|
37
70
|
end
|
38
71
|
|
39
|
-
def success(locals={})
|
40
|
-
halt erb :success, :
|
72
|
+
def success(locals = {})
|
73
|
+
halt erb :success, locals: locals
|
41
74
|
end
|
42
75
|
|
43
76
|
def forbidden
|
@@ -51,17 +84,18 @@ module AddToOrg
|
|
51
84
|
end
|
52
85
|
|
53
86
|
# request a GitHub (authenticated) URL
|
54
|
-
get
|
55
|
-
|
87
|
+
get '/*' do
|
56
88
|
path = request.path || "/#{team_id}"
|
57
89
|
halt redirect "https://github.com#{path}", 302 if member?
|
58
90
|
forbidden unless valid?
|
59
91
|
|
60
92
|
if add
|
61
|
-
success({ :
|
93
|
+
success({ redirect: "https://github.com#{path}", org_id: org_id })
|
62
94
|
else
|
63
95
|
error
|
64
96
|
end
|
65
97
|
end
|
66
98
|
end
|
67
99
|
end
|
100
|
+
|
101
|
+
Dotenv.load unless AddToOrg::App.production?
|
data/script/cibuild
CHANGED
@@ -1,80 +1,88 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
+
describe 'AddToOrgHelpers' do
|
5
6
|
class TestHelper
|
6
7
|
include AddToOrg::Helpers
|
7
8
|
|
8
9
|
def github_user
|
9
|
-
User.make({
|
10
|
+
User.make({ 'login' => 'benbaltertest' }, 'asdf1234')
|
10
11
|
end
|
11
12
|
|
12
|
-
def initialize(path=nil)
|
13
|
+
def initialize(path = nil)
|
13
14
|
@path = path
|
14
15
|
end
|
15
16
|
|
16
17
|
def request
|
17
|
-
Rack::Request.new(
|
18
|
+
Rack::Request.new('PATH_INFO' => @path)
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
21
|
-
before
|
22
|
+
before do
|
22
23
|
@helper = TestHelper.new
|
23
24
|
end
|
24
25
|
|
25
|
-
it
|
26
|
-
expect(@helper.client.class).to eql(Octokit::Client)
|
27
|
-
expect(@helper.client.instance_variable_get(
|
26
|
+
it 'initializes the client' do
|
27
|
+
expect(@helper.send(:client).class).to eql(Octokit::Client)
|
28
|
+
expect(@helper.send(:client).instance_variable_get('@access_token')).to eql('asdf1234')
|
28
29
|
end
|
29
30
|
|
30
|
-
it
|
31
|
-
with_env
|
32
|
-
expect(@helper.sudo_client.class).to eql(Octokit::Client)
|
33
|
-
expect(@helper.sudo_client.instance_variable_get(
|
31
|
+
it 'initializes the sudo client' do
|
32
|
+
with_env 'GITHUB_TOKEN', 'SUDO_TOKEN' do
|
33
|
+
expect(@helper.send(:sudo_client).class).to eql(Octokit::Client)
|
34
|
+
expect(@helper.send(:sudo_client).instance_variable_get('@access_token')).to eql('SUDO_TOKEN')
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
it
|
38
|
-
stub_request(:get,
|
39
|
-
|
40
|
-
expect(@helper.verified_emails.count).to
|
41
|
-
expect(@helper.verified_emails.first[:email]).to eql(
|
38
|
+
it 'retrieves a users verified emails' do
|
39
|
+
stub_request(:get, 'https://api.github.com/user/emails')
|
40
|
+
.to_return(status: 200, body: fixture('emails.json'), headers: { 'Content-Type' => 'application/json' })
|
41
|
+
expect(@helper.verified_emails.count).to be(1)
|
42
|
+
expect(@helper.verified_emails.first[:email]).to eql('octocat@github.com')
|
42
43
|
end
|
43
44
|
|
44
|
-
it
|
45
|
-
with_env
|
46
|
-
expect(@helper.org_id).to eql(
|
45
|
+
it 'retrieves the org id' do
|
46
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
47
|
+
expect(@helper.send(:org_id)).to eql('some_org')
|
47
48
|
end
|
48
49
|
end
|
49
50
|
|
50
|
-
it
|
51
|
-
with_env
|
52
|
-
expect(@helper.team_id).to eql(
|
51
|
+
it 'retrieves the team id' do
|
52
|
+
with_env 'GITHUB_TEAM_ID', '1234' do
|
53
|
+
expect(@helper.send(:team_id)).to eql('1234')
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
it
|
57
|
-
with_env
|
58
|
-
stub_request(:get,
|
59
|
-
|
60
|
-
expect(@helper.member?).to
|
57
|
+
it 'knows if a user is an org member' do
|
58
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
59
|
+
stub_request(:get, 'https://api.github.com/orgs/some_org/members/benbaltertest')
|
60
|
+
.to_return(status: 204)
|
61
|
+
expect(@helper.send(:member?)).to be(true)
|
61
62
|
|
62
|
-
stub_request(:get,
|
63
|
-
|
64
|
-
expect(@helper.member?).to
|
63
|
+
stub_request(:get, 'https://api.github.com/orgs/some_org/members/benbaltertest')
|
64
|
+
.to_return(status: 404)
|
65
|
+
expect(@helper.send(:member?)).to be(false)
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
68
|
-
it
|
69
|
-
with_env
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
69
|
+
it 'knows how to add a member to an org' do
|
70
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
71
|
+
with_env 'GITHUB_TEAM_ID', '1234' do
|
72
|
+
stub = stub_request(:put, 'https://api.github.com/teams/1234/memberships/benbaltertest')
|
73
|
+
.to_return(status: 204)
|
74
|
+
@helper.send(:add)
|
75
|
+
expect(stub).to have_been_requested
|
76
|
+
end
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
77
|
-
it
|
78
|
-
|
80
|
+
it 'throws an error if valid? is not defined' do
|
81
|
+
stub_request(:get, 'https://api.github.com/user/emails')
|
82
|
+
.to_return(status: 200, body: fixture('emails.json'), headers: { 'Content-Type' => 'application/json' })
|
83
|
+
|
84
|
+
AddToOrg.validator = nil
|
85
|
+
error = 'You must define a custom validator to determine eligibility'
|
86
|
+
expect { @helper.valid? }.to raise_error(error)
|
79
87
|
end
|
80
88
|
end
|
data/spec/add-to-org_spec.rb
CHANGED
@@ -1,32 +1,38 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
+
describe 'config' do
|
6
|
+
%i[views_dir public_dir validator].each do |var|
|
7
|
+
after do
|
8
|
+
AddToOrg.send("#{var}=", nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "accepts #{var}" do
|
12
|
+
expected = SecureRandom.hex
|
13
|
+
AddToOrg.send("#{var}=", expected)
|
14
|
+
expect(AddToOrg.send(var)).to eql(expected)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'logged out user' do
|
5
20
|
include Rack::Test::Methods
|
6
21
|
|
7
22
|
def app
|
8
23
|
AddToOrg::App
|
9
24
|
end
|
10
25
|
|
11
|
-
it
|
12
|
-
get
|
13
|
-
expect(last_response.status).to
|
26
|
+
it 'asks you to log in' do
|
27
|
+
get '/'
|
28
|
+
expect(last_response.status).to be(302)
|
14
29
|
expect(last_response.headers['Location']).to match(%r{^https://github\.com/login/oauth/authorize})
|
15
30
|
end
|
16
31
|
end
|
17
32
|
|
18
|
-
describe
|
19
|
-
|
33
|
+
describe 'logged in user' do
|
20
34
|
include Rack::Test::Methods
|
21
35
|
|
22
|
-
module AddToOrg
|
23
|
-
class App < Sinatra::Base
|
24
|
-
def valid?
|
25
|
-
verified_emails.any? { |email| email[:email] =~ /@github\.com$/}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
36
|
def app
|
31
37
|
AddToOrg::App
|
32
38
|
end
|
@@ -36,71 +42,98 @@ describe "logged in user" do
|
|
36
42
|
login_as @user
|
37
43
|
end
|
38
44
|
|
39
|
-
it
|
40
|
-
with_env
|
41
|
-
stub_request(:get,
|
42
|
-
|
43
|
-
get
|
44
|
-
expect(last_response.status).to
|
45
|
-
expect(last_response.headers['Location']).to eql(
|
46
|
-
|
47
|
-
get
|
48
|
-
expect(last_response.status).to
|
49
|
-
expect(last_response.headers['Location']).to eql(
|
50
|
-
|
51
|
-
get
|
52
|
-
expect(last_response.status).to
|
53
|
-
expect(last_response.headers['Location']).to eql(
|
45
|
+
it 'redirects if the user is a member' do
|
46
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
47
|
+
stub_request(:get, 'https://api.github.com/orgs/some_org/members/benbaltertest')
|
48
|
+
.to_return(status: 204)
|
49
|
+
get '/'
|
50
|
+
expect(last_response.status).to be(302)
|
51
|
+
expect(last_response.headers['Location']).to eql('https://github.com/')
|
52
|
+
|
53
|
+
get '/foo'
|
54
|
+
expect(last_response.status).to be(302)
|
55
|
+
expect(last_response.headers['Location']).to eql('https://github.com/foo')
|
56
|
+
|
57
|
+
get '/foo/bar'
|
58
|
+
expect(last_response.status).to be(302)
|
59
|
+
expect(last_response.headers['Location']).to eql('https://github.com/foo/bar')
|
54
60
|
end
|
55
61
|
end
|
56
62
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
%i[proc block lambda].each do |method|
|
64
|
+
describe "with validator passed as a #{method}" do
|
65
|
+
before do
|
66
|
+
case method
|
67
|
+
when :block
|
68
|
+
AddToOrg.set_validator do |_github_user, verified_emails, _client|
|
69
|
+
verified_emails.any? { |email| email[:email] =~ /@github\.com$/ }
|
70
|
+
end
|
71
|
+
when :proc
|
72
|
+
AddToOrg.validator = proc { |_github_user, verified_emails, _client|
|
73
|
+
verified_emails.any? { |email| email[:email] =~ /@github\.com$/ }
|
74
|
+
}
|
75
|
+
when :lambda
|
76
|
+
AddToOrg.validator = lambda { |_github_user, verified_emails, _client|
|
77
|
+
verified_emails.any? { |email| email[:email] =~ /@github\.com$/ }
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
70
81
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
82
|
+
it 'denies acccess to invalid users' do
|
83
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
84
|
+
stub_request(:get, 'https://api.github.com/orgs/some_org/members/benbaltertest')
|
85
|
+
.to_return(status: 404)
|
75
86
|
|
76
|
-
|
77
|
-
|
87
|
+
stub_request(:get, 'https://api.github.com/user/emails')
|
88
|
+
.to_return(status: 200, body: fixture('invalid_emails.json'), headers: { 'Content-Type' => 'application/json' })
|
78
89
|
|
79
|
-
|
80
|
-
|
90
|
+
get '/'
|
91
|
+
expect(last_response.status).to be(403)
|
92
|
+
expect(last_response.body).to match(/We're unable to verify your eligibility at this time/)
|
93
|
+
end
|
94
|
+
end
|
81
95
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
96
|
+
it 'tries to add valid users' do
|
97
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
98
|
+
with_env 'GITHUB_TEAM_ID', '1234' do
|
99
|
+
stub_request(:get, 'https://api.github.com/orgs/some_org/members/benbaltertest')
|
100
|
+
.to_return(status: 404)
|
101
|
+
|
102
|
+
stub_request(:get, 'https://api.github.com/user/emails')
|
103
|
+
.to_return(status: 200, body: fixture('emails.json'), headers: { 'Content-Type' => 'application/json' })
|
104
|
+
|
105
|
+
stub = stub_request(:put, 'https://api.github.com/teams/1234/memberships/benbaltertest')
|
106
|
+
.to_return(status: 204)
|
107
|
+
|
108
|
+
get '/foo'
|
109
|
+
expect(stub).to have_been_requested
|
110
|
+
expect(last_response.status).to be(200)
|
111
|
+
expect(last_response.body).to match(/confirm your invitation to join the organization/)
|
112
|
+
expect(last_response.body).to match(%r{https://github.com/orgs/some_org/invitation})
|
113
|
+
expect(last_response.body).to match(%r{\?return_to=https://github.com/foo})
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
88
117
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
118
|
+
it 'includes the requested URL' do
|
119
|
+
with_env 'GITHUB_ORG_ID', 'some_org' do
|
120
|
+
with_env 'GITHUB_TEAM_ID', '1234' do
|
121
|
+
stub_request(:get, 'https://api.github.com/orgs/some_org/members/benbaltertest')
|
122
|
+
.to_return(status: 404)
|
93
123
|
|
94
|
-
|
95
|
-
|
124
|
+
stub_request(:get, 'https://api.github.com/user/emails')
|
125
|
+
.to_return(status: 200, body: fixture('emails.json'), headers: { 'Content-Type' => 'application/json' })
|
96
126
|
|
97
|
-
|
98
|
-
|
127
|
+
stub = stub_request(:put, 'https://api.github.com/teams/1234/memberships/benbaltertest')
|
128
|
+
.to_return(status: 204)
|
99
129
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
130
|
+
get '/foo/bar'
|
131
|
+
expect(stub).to have_been_requested
|
132
|
+
expect(last_response.status).to be(200)
|
133
|
+
expect(last_response.body).to match(Regexp.new('<a href="https://github.com/foo/bar">https://github.com/foo/bar</a>'))
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
104
137
|
end
|
105
138
|
end
|
106
139
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
2
4
|
require 'fileutils'
|
5
|
+
require 'securerandom'
|
3
6
|
|
4
7
|
ENV['RACK_ENV'] = 'test'
|
5
|
-
|
8
|
+
ENV['GITHUB_CLIENT_ID'] = 'CLIENT_ID'
|
9
|
+
ENV['GITHUB_CLIENT_SECRET'] = 'CLIENT_SECRET'
|
10
|
+
$LOAD_PATH.push File.join(File.dirname(__FILE__), '..', 'lib')
|
6
11
|
|
7
12
|
require 'rack/test'
|
8
13
|
require 'sinatra/auth/github'
|
9
14
|
require 'sinatra/auth/github/test/test_helper'
|
10
15
|
require 'webmock/rspec'
|
11
16
|
|
12
|
-
require_relative
|
17
|
+
require_relative '../lib/add-to-org'
|
13
18
|
WebMock.disable_net_connect!
|
14
19
|
|
15
20
|
RSpec.configure do |config|
|
@@ -24,7 +29,6 @@ def fixture(fixture)
|
|
24
29
|
File.open(fixture_path(fixture)).read
|
25
30
|
end
|
26
31
|
|
27
|
-
|
28
32
|
def with_env(key, value)
|
29
33
|
old_env = ENV[key]
|
30
34
|
ENV[key] = value
|
@@ -33,16 +37,16 @@ def with_env(key, value)
|
|
33
37
|
end
|
34
38
|
|
35
39
|
class User < Warden::GitHub::User
|
36
|
-
def self.make(attrs = {}, token=nil)
|
40
|
+
def self.make(attrs = {}, token = nil)
|
37
41
|
default_attrs = {
|
38
|
-
'login'
|
39
|
-
'name'
|
40
|
-
'email'
|
41
|
-
'company' =>
|
42
|
-
'gravatar_id' => 'a'*32,
|
43
|
-
'avatar_url'
|
42
|
+
'login' => 'test_user',
|
43
|
+
'name' => 'Test User',
|
44
|
+
'email' => 'test@example.com',
|
45
|
+
'company' => 'GitHub',
|
46
|
+
'gravatar_id' => 'a' * 32,
|
47
|
+
'avatar_url' => 'https://a249.e.akamai.net/assets.github.com/images/gravatars/gravatar-140.png?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png'
|
44
48
|
}
|
45
49
|
default_attrs.merge! attrs
|
46
|
-
User.new(default_attrs,token)
|
50
|
+
User.new(default_attrs, token)
|
47
51
|
end
|
48
52
|
end
|
metadata
CHANGED
@@ -1,73 +1,73 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: add-to-org
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Balter
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: dotenv
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
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: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: octokit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '4.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '4.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rack-ssl-enforcer
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0.2'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0.2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '0
|
61
|
+
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '0
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: sinatra_auth_github
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
@@ -81,19 +81,33 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '2.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: pry
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
type: :
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - "
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rack-test
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version: '
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: rspec
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,66 +123,85 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '3.1'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: rubocop
|
113
127
|
requirement: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- - "
|
129
|
+
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0
|
131
|
+
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- - "
|
136
|
+
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
140
|
+
name: rubocop-performance
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
128
142
|
requirements:
|
129
|
-
- - "
|
143
|
+
- - ">="
|
130
144
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
145
|
+
version: '0'
|
132
146
|
type: :development
|
133
147
|
prerelease: false
|
134
148
|
version_requirements: !ruby/object:Gem::Requirement
|
135
149
|
requirements:
|
136
|
-
- - "
|
150
|
+
- - ">="
|
137
151
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
152
|
+
version: '0'
|
139
153
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
154
|
+
name: rubocop-rspec
|
141
155
|
requirement: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
|
-
- - "
|
157
|
+
- - ">="
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0
|
159
|
+
version: '0'
|
146
160
|
type: :development
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
|
-
- - "
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: webmock
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
151
179
|
- !ruby/object:Gem::Version
|
152
|
-
version: '0
|
180
|
+
version: '0'
|
153
181
|
description: A simple Oauth App to automatically add users to an organization.
|
154
182
|
email: ben.balter@github.com
|
155
183
|
executables: []
|
156
184
|
extensions: []
|
157
185
|
extra_rdoc_files: []
|
158
186
|
files:
|
187
|
+
- ".bowerrc"
|
188
|
+
- ".github/workflows/ci.yml"
|
159
189
|
- ".gitignore"
|
160
|
-
- ".
|
190
|
+
- ".rubocop.yml"
|
191
|
+
- ".rubocop_todo.yml"
|
161
192
|
- ".travis.yml"
|
162
193
|
- Gemfile
|
163
194
|
- LICENSE.md
|
164
195
|
- README.md
|
165
196
|
- Rakefile
|
166
197
|
- add-to-org.gemspec
|
198
|
+
- bower.json
|
167
199
|
- lib/add-to-org.rb
|
168
200
|
- lib/add-to-org/helpers.rb
|
169
201
|
- lib/add-to-org/version.rb
|
170
202
|
- lib/add-to-org/views/error.erb
|
171
203
|
- lib/add-to-org/views/forbidden.erb
|
204
|
+
- lib/add-to-org/views/layout.erb
|
172
205
|
- lib/add-to-org/views/success.erb
|
173
206
|
- script/bootstrap
|
174
207
|
- script/cibuild
|
@@ -183,7 +216,7 @@ homepage: https://github.com/benbalter/add-to-org
|
|
183
216
|
licenses:
|
184
217
|
- MIT
|
185
218
|
metadata: {}
|
186
|
-
post_install_message:
|
219
|
+
post_install_message:
|
187
220
|
rdoc_options: []
|
188
221
|
require_paths:
|
189
222
|
- lib
|
@@ -198,9 +231,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
198
231
|
- !ruby/object:Gem::Version
|
199
232
|
version: '0'
|
200
233
|
requirements: []
|
201
|
-
|
202
|
-
|
203
|
-
signing_key:
|
234
|
+
rubygems_version: 3.2.28
|
235
|
+
signing_key:
|
204
236
|
specification_version: 4
|
205
237
|
summary: A simple Oauth App to automatically add users to an organization
|
206
238
|
test_files:
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.2.3
|