add-to-org 2.2.0 → 3.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|