jekyll-auth 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +20 -0
- data/Gemfile +1 -1
- data/README.md +23 -23
- data/Rakefile +4 -4
- data/bin/jekyll-auth +24 -23
- data/jekyll-auth.gemspec +25 -23
- data/lib/jekyll-auth.rb +13 -13
- data/lib/jekyll_auth/auth_site.rb +10 -15
- data/lib/jekyll_auth/commands.rb +7 -8
- data/lib/jekyll_auth/config.rb +2 -2
- data/lib/jekyll_auth/config_error.rb +1 -2
- data/lib/jekyll_auth/helpers.rb +3 -3
- data/lib/jekyll_auth/jekyll_site.rb +4 -5
- data/lib/jekyll_auth/version.rb +1 -1
- data/script/cibuild +5 -0
- data/spec/jekyll_auth_auth_site_spec.rb +14 -16
- data/spec/jekyll_auth_bin_spec.rb +9 -10
- data/spec/jekyll_auth_commands_spec.rb +4 -5
- data/spec/jekyll_auth_helpers_spec.rb +1 -2
- data/spec/jekyll_auth_jekyll_site_spec.rb +0 -1
- data/spec/jekyll_auth_spec.rb +3 -4
- data/spec/spec_helper.rb +11 -9
- data/templates/Rakefile +1 -1
- data/templates/config.ru +1 -1
- metadata +38 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5252fb3ba4db62cb22f5f9949f54a2e0612ed060
|
4
|
+
data.tar.gz: ae51f402692073b5b79942f62af6885533bf41fc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c85daf40909c0eca989d2c468fd68edc67d4fea09b197f64dd06194f9bfb6a045849e8766720427ba683023b80ba58e154de8d9952c2a65cd3054640e13291d8
|
7
|
+
data.tar.gz: 1409e332aca6db366fa2dc1c4c8a00aea75e5dbd38f78800b21eb78f4c71ffe64d94790f8b5903758c427ba7de188db89bd2f8b1898f9c0165989d3f423e57c3
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
jekyll: .rubocop.yml
|
3
|
+
|
4
|
+
Style/Documentation:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Metrics/MethodLength:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Metrics/LineLength:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/FileName:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Metrics/BlockLength:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Style/DoubleNegation:
|
20
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -23,21 +23,21 @@ But what if you only want to share that site with a select number of people? Bef
|
|
23
23
|
|
24
24
|
1. Navigate to [the GitHub app registration page](https://github.com/settings/applications/new)
|
25
25
|
2. Give your app a name
|
26
|
-
3. Tell GitHub the URL you want the app to eventually live at. If using a free Heroku account, this will be something like http://my-site.herokuapp.com
|
27
|
-
4. Specify the callback URL; should be like this: https://my-site.herokuapp.com/auth/github/callback
|
26
|
+
3. Tell GitHub the URL you want the app to eventually live at. If using a free Heroku account, this will be something like <http://my-site.herokuapp.com>
|
27
|
+
4. Specify the callback URL; should be like this: <https://my-site.herokuapp.com/auth/github/callback>; note that this is **https**, not http.
|
28
28
|
5. Hit Save, but leave the page open, you'll need some of the information in a moment
|
29
29
|
|
30
|
-
Remember the 'my-site' part for later on when using `heroku create`. Also, my-site is often called 'app-name' in Heroku
|
30
|
+
Remember the 'my-site' part for later on when using `heroku create`. Also, my-site is often called 'app-name' in Heroku documentation.
|
31
31
|
|
32
32
|
### Add Jekyll Auth to your site
|
33
33
|
|
34
|
-
1. Within your new site repository or orphaned github [branch](https://help.github.com/articles/creating-project-pages-manually/) (the branch could be named anything except 'gh-pages' since this would then be public on
|
34
|
+
1. Within your new site repository or orphaned github [branch](https://help.github.com/articles/creating-project-pages-manually/) (the branch could be named anything except 'gh-pages' since this would then be public on GitHub!), add `gem 'jekyll-auth'` to your `Gemfile` or if you don't already have a `Gemfile`, create a file called `Gemfile` in the root of your site's repository with the following content:
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
```ruby
|
37
|
+
source "https://rubygems.org"
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
gem 'jekyll-auth'
|
40
|
+
```
|
41
41
|
|
42
42
|
2. `cd` into your project's directory and run `bundle install`. If you get an error using `bundle install`, see Troubleshooting below.
|
43
43
|
|
@@ -55,20 +55,20 @@ Run `bundle exec jekyll-auth setup --client_id XXX --client_secret XXX --org_nam
|
|
55
55
|
|
56
56
|
1. You may need to add and commit the files generated by `jekyll-auth new` to Git before continuing
|
57
57
|
2. Make sure you have [the Heroku toolbelt](https://toolbelt.heroku.com/) installed
|
58
|
-
3. Run `heroku create my-site` from your site's directory; make sure my-site matches what you specified in the
|
58
|
+
3. Run `heroku create my-site` from your site's directory; make sure my-site matches what you specified in the GitHub application registration above.
|
59
59
|
4. `heroku config:set GITHUB_CLIENT_ID=XXX GITHUB_CLIENT_SECRET=XXX GITHUB_ORG_NAME=XXX` (or `GITHUB_TEAM_ID`)
|
60
|
-
5. `git push heroku`, or if you are maintaining the site in an orphaned branch of your
|
60
|
+
5. `git push heroku`, or if you are maintaining the site in an orphaned branch of your GitHub repo (say 'heroku-pages'), do `git push heroku heroku-pages:master`
|
61
61
|
6. `heroku open` to open the site in your browser
|
62
62
|
|
63
|
-
#### Find the
|
63
|
+
#### Find the Organization ID (needed to find Team ID)
|
64
64
|
|
65
|
-
If you need to find an organization's ID, you can use the following
|
65
|
+
If you need to find an organization's ID, you can use the following cURL command:
|
66
66
|
|
67
67
|
```
|
68
68
|
curl https://api.github.com/orgs/{org_name}
|
69
69
|
```
|
70
70
|
|
71
|
-
#### Finding the
|
71
|
+
#### Finding the Team ID
|
72
72
|
|
73
73
|
If you need help finding a team's numeric ID, you can use the `jekyll-auth team_id` command.
|
74
74
|
|
@@ -78,13 +78,13 @@ For example, to find the team ID for @jekyll/maintainers you'd run the command:
|
|
78
78
|
jekyll-auth team_id --org jekyll --team maintainers
|
79
79
|
```
|
80
80
|
|
81
|
-
You'll want to add a [personal access token](https://github.com/settings/tokens/new) to your `.env` file so that Jekyll-Auth can make the necessary API request, but the command will run you through the process if you
|
81
|
+
You'll want to add a [personal access token](https://github.com/settings/tokens/new) to your `.env` file so that Jekyll-Auth can make the necessary API request, but the command will run you through the process if you do not provide this.
|
82
82
|
|
83
83
|
## Configuration
|
84
84
|
|
85
85
|
### Whitelisting
|
86
86
|
|
87
|
-
Don't want to require authentication for every part of your site? Fine! Add a whitelist to your Jekyll's
|
87
|
+
Don't want to require authentication for every part of your site? Fine! Add a whitelist to your Jekyll's **config.yml** file:
|
88
88
|
|
89
89
|
```yaml
|
90
90
|
jekyll_auth:
|
@@ -94,7 +94,7 @@ jekyll_auth:
|
|
94
94
|
|
95
95
|
`jekyll_auth.whitelist` takes an array of regular expressions as strings. The default auth behavior checks (and blocks) against root (`/`). Any path defined in the whitelist won't require authentication on your site.
|
96
96
|
|
97
|
-
What if you want to go the other way, and unauthenticate the entire site
|
97
|
+
What if you want to go the other way, and unauthenticate the entire site *except* for certain portions? You can define some regex magic for that:
|
98
98
|
|
99
99
|
```yaml
|
100
100
|
jekyll_auth:
|
@@ -123,7 +123,7 @@ Want to run it locally?
|
|
123
123
|
|
124
124
|
### Without authentication
|
125
125
|
|
126
|
-
Just run `jekyll serve` as you would normally
|
126
|
+
Just run `jekyll serve` as you would normally.
|
127
127
|
|
128
128
|
### With authentication
|
129
129
|
|
@@ -132,7 +132,7 @@ Just run `jekyll serve` as you would normally
|
|
132
132
|
3. `export GITHUB_ORG_NAME=[org name]` or `export GITHUB_TEAM_ID=[team id]` or `export GITHUB_TEAM_IDS=1234,5678`
|
133
133
|
4. `jekyll-auth serve`
|
134
134
|
|
135
|
-
*Pro-tip #1:* For sanity sake, and to avoid problems with your callback URL, you may want to have two apps, one with a local
|
135
|
+
*Pro-tip #1:* For sanity's sake, and to avoid problems with your callback URL, you may want to have two apps, one with a local Oauth callback, and one for production if you're going to be testing auth locally.
|
136
136
|
|
137
137
|
*Pro-tip #2*: Jekyll Auth supports [dotenv](https://github.com/bkeepers/dotenv) out of the box. You can create a `.env` file in the root of site and add your configuration variables there. It's ignored by `.gitignore` if you use `jekyll-auth new`, but be sure not to accidentally commit your `.env` file. Here's what your `.env` file might look like:
|
138
138
|
|
@@ -146,11 +146,11 @@ GITHUB_TEAM_ID=12345
|
|
146
146
|
|
147
147
|
Every time you push to Heroku, we take advantage of the fact that Heroku automatically runs the `rake assets:precompile` command (normally used for Rails sites) to build our Jekyll site and store it statically, just like GitHub pages would.
|
148
148
|
|
149
|
-
Anytime a request comes in for a page, we run it through [Sinatra](http://www.sinatrarb.com/) (using the `_site` folder as the static file folder, just as `public` would be normally), and authenticate it using [
|
149
|
+
Anytime a request comes in for a page, we run it through [Sinatra](http://www.sinatrarb.com/) (using the `_site` folder as the static file folder, just as `public` would be normally), and authenticate it using [sinatra\_auth\_github](https://github.com/atmos/sinatra_auth_github).
|
150
150
|
|
151
151
|
If they're in the org, they get the page. Otherwise, all they ever get is [the bouncer](http://octodex.github.com/bouncer/).
|
152
152
|
|
153
|
-
## Upgrading from Jekyll Auth
|
153
|
+
## Upgrading from Jekyll Auth < 0.1.0
|
154
154
|
|
155
155
|
1. `cd` to your project directory
|
156
156
|
2. `rm config.ru`
|
@@ -163,6 +163,7 @@ If they're in the org, they get the page. Otherwise, all they ever get is [the b
|
|
163
163
|
|
164
164
|
* **ERROR: YOUR SITE COULD NOT BE BUILT** during install, either locally or on Heroku. You likely need to add `exclude: [vendor]` to `_config.yml` in your branch's root directory (create the file if it does not exist already). If you still have problems on the *local* install, you may have better luck using `bundle install --deployment`, but be sure to add the resulting 'vendor' directory to .gitignore. For completeness, the full error may look something like this:
|
165
165
|
|
166
|
+
|
166
167
|
```
|
167
168
|
remote: Configuration file: none
|
168
169
|
remote: ERROR: YOUR SITE COULD NOT BE BUILT:
|
@@ -170,10 +171,9 @@ remote: ------------------------------------
|
|
170
171
|
remote: Invalid date '0000-00-00': Post '/vendor/bundle/ruby/2.0.0/gems/jekyll-2.5.3/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the filename.
|
171
172
|
```
|
172
173
|
|
173
|
-
* **Pushing to heroku**. If you are working from a new
|
174
|
+
* **Pushing to heroku**. If you are working from a new GitHub-cloned repo (where you have not run `heroku create`), you may also want to push to Heroku. Instead of adding the remote in the standard way with Git, do this:
|
175
|
+
|
174
176
|
|
175
177
|
```
|
176
178
|
heroku git:remote -a my-site
|
177
179
|
```
|
178
|
-
|
179
|
-
|
data/Rakefile
CHANGED
@@ -4,17 +4,17 @@ require 'bundler'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'dotenv'
|
6
6
|
|
7
|
-
task :
|
7
|
+
task default: [:spec]
|
8
8
|
|
9
9
|
task :site do
|
10
10
|
Dotenv.load
|
11
|
-
FileUtils.chdir
|
11
|
+
FileUtils.chdir 'templates'
|
12
12
|
`bundle exec jekyll-auth`
|
13
13
|
end
|
14
14
|
|
15
15
|
require 'rspec/core/rake_task'
|
16
|
-
desc
|
16
|
+
desc 'Run specs'
|
17
17
|
RSpec::Core::RakeTask.new do |t|
|
18
18
|
t.pattern = 'spec/**/*_spec.rb'
|
19
|
-
t.rspec_opts = [
|
19
|
+
t.rspec_opts = ['--order', 'rand', '--color']
|
20
20
|
end
|
data/bin/jekyll-auth
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# Command-line interface for jekyll-auth
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
4
|
+
require "mercenary"
|
5
|
+
require "jekyll-auth"
|
6
|
+
require "open3"
|
7
7
|
|
8
8
|
Mercenary.program("jekyll-auth") do |p|
|
9
|
-
p.version
|
9
|
+
p.version JekyllAuth::VERSION
|
10
10
|
p.description "A simple way to use Github OAuth to serve a protected jekyll site to your GitHub organization"
|
11
|
-
p.syntax
|
11
|
+
p.syntax "jekyll-auth <subcommand> options"
|
12
12
|
|
13
13
|
p.command(:new) do |c|
|
14
|
-
c.syntax
|
14
|
+
c.syntax "new"
|
15
15
|
c.description "Initialize an existing Jekyll site as a Jekyll Auth site"
|
16
|
-
c.action do |
|
17
|
-
|
16
|
+
c.action do |_args, _options|
|
18
17
|
JekyllAuth::Commands.copy_templates
|
19
18
|
|
20
19
|
if JekyllAuth::Commands.changed?
|
@@ -29,23 +28,22 @@ Mercenary.program("jekyll-auth") do |p|
|
|
29
28
|
# Called by Rake task, to allow the gem
|
30
29
|
# to add functionality here in the future
|
31
30
|
p.command(:build) do |c|
|
32
|
-
c.syntax
|
31
|
+
c.syntax "build"
|
33
32
|
c.description "Build the Jekyll site"
|
34
|
-
c.action do |
|
35
|
-
require
|
33
|
+
c.action do |_args, options|
|
34
|
+
require "jekyll"
|
36
35
|
Jekyll::Commands::Build.process(options)
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
40
39
|
p.command(:team_id) do |c|
|
41
|
-
c.syntax
|
40
|
+
c.syntax "team_id --org <ORG> --team <TEAM>"
|
42
41
|
c.description "Retrieve a team's ID"
|
43
|
-
c.option
|
44
|
-
c.option
|
45
|
-
|
46
|
-
c.action do |args, options|
|
42
|
+
c.option "org", "--org <ORG>", 'The GitHub Organization, e.g., "jekyll"'
|
43
|
+
c.option "team", "--team <TEAM>", 'The team name, e.g., "maintainers"'
|
47
44
|
|
48
|
-
|
45
|
+
c.action do |_args, options|
|
46
|
+
unless JekyllAuth::Commands.env_var_set? "GITHUB_TOKEN"
|
49
47
|
puts "You'll need to go to https://github.com/settings/tokens/new and create a personal access token".red
|
50
48
|
puts "Once you've got the token, prefix the jekyll-auth command with GITHUB_TOKEN=[YOUR TOKEN]".red
|
51
49
|
puts "You can also add it to a `.env` file in this directory".red
|
@@ -74,10 +72,12 @@ Mercenary.program("jekyll-auth") do |p|
|
|
74
72
|
p.command(:serve) do |c|
|
75
73
|
c.syntax "serve"
|
76
74
|
c.description "Run Jekyll Auth site locally"
|
77
|
-
c.
|
75
|
+
c.option "host", "--host <HOST>", "Listen at the given hostname, e.g., 127.0.0.1"
|
76
|
+
c.option "port", "--port <PORT>", "Listen on the given port, e.g., 4000"
|
78
77
|
|
78
|
+
c.action do |_args, options|
|
79
79
|
# Ensure environmental variables are set
|
80
|
-
unless
|
80
|
+
unless %w(GITHUB_CLIENT_ID GITHUB_CLIENT_SECRET).all? { |v| JekyllAuth::Commands.env_var_set?(v) }
|
81
81
|
puts "Whoops. Looks like you forgot to tell Jekyll Auth about your app".red
|
82
82
|
puts "Be sure to run export GITHUB_CLIENT_ID=[client id], export GITHUB_CLIENT_SECRET=[client secret], and export GITHUB_ORG_NAME=[org name] (or GITHUB_TEAM_ID)".red
|
83
83
|
puts "See the readme for more information on where to find these".red
|
@@ -87,10 +87,12 @@ Mercenary.program("jekyll-auth") do |p|
|
|
87
87
|
# build site
|
88
88
|
p.go ["build"]
|
89
89
|
|
90
|
+
host = options["host"] || "0.0.0.0"
|
91
|
+
port = options["port"] || "4000"
|
92
|
+
|
90
93
|
puts "Spinning up the server with authentication. Use CTRL-C to stop."
|
91
94
|
puts "To preview the site without authentication, use the `jekyll serve` command"
|
92
|
-
JekyllAuth::Commands.execute_command "bundle", "exec", "rackup", "-
|
93
|
-
|
95
|
+
JekyllAuth::Commands.execute_command "bundle", "exec", "rackup", "-o", host, "-p", port
|
94
96
|
end
|
95
97
|
end
|
96
98
|
|
@@ -101,8 +103,7 @@ Mercenary.program("jekyll-auth") do |p|
|
|
101
103
|
c.option "client_secret", "--client_secret", "Your oauth app client secret"
|
102
104
|
c.option "team_id", "--team_id", "The team to authenticate against"
|
103
105
|
c.option "org_name", "--org_name", "An organization to authenticate against"
|
104
|
-
c.action do |
|
105
|
-
|
106
|
+
c.action do |_args, options|
|
106
107
|
if find_executable("heroku").nil?
|
107
108
|
say "Looks like we're missing the Heroku client. Let's see if we can't install it..."
|
108
109
|
JekyllAuth::Commands.execute_command "wget", "-qO-", "https://toolbelt.heroku.com/install.sh", "|", "sh"
|
data/jekyll-auth.gemspec
CHANGED
@@ -1,31 +1,33 @@
|
|
1
1
|
require './lib/jekyll_auth/version'
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
4
|
+
s.name = 'jekyll-auth'
|
5
5
|
s.version = JekyllAuth::VERSION
|
6
|
-
s.summary =
|
7
|
-
s.description =
|
8
|
-
s.authors =
|
9
|
-
s.email =
|
10
|
-
s.homepage =
|
11
|
-
s.license =
|
6
|
+
s.summary = 'A simple way to use GitHub OAuth to serve a protected jekyll site to your GitHub organization'
|
7
|
+
s.description = 'A simple way to use GitHub OAuth to serve a protected jekyll site to your GitHub organization.'
|
8
|
+
s.authors = 'Ben Balter'
|
9
|
+
s.email = 'ben@balter.com'
|
10
|
+
s.homepage = 'https://github.com/benbalter/jekyll-auth'
|
11
|
+
s.license = 'MIT'
|
12
12
|
s.files = `git ls-files`.split("\n")
|
13
13
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
-
s.require_paths = [
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
15
|
+
s.require_paths = ['lib']
|
16
16
|
|
17
|
-
s.add_dependency
|
18
|
-
s.add_dependency
|
19
|
-
s.add_dependency
|
20
|
-
s.add_dependency
|
21
|
-
s.add_dependency
|
22
|
-
s.add_dependency
|
23
|
-
s.add_dependency
|
24
|
-
s.add_dependency
|
25
|
-
s.add_dependency 'safe_yaml',
|
26
|
-
s.add_dependency
|
27
|
-
s.
|
28
|
-
s.add_development_dependency
|
29
|
-
s.add_development_dependency
|
30
|
-
s.add_development_dependency
|
17
|
+
s.add_dependency 'jekyll', '~> 3.0'
|
18
|
+
s.add_dependency 'sinatra-index', '~> 0.0'
|
19
|
+
s.add_dependency 'sinatra_auth_github', '~> 1.1'
|
20
|
+
s.add_dependency 'rack', '~> 1.6'
|
21
|
+
s.add_dependency 'dotenv', '~> 2.0'
|
22
|
+
s.add_dependency 'rake', '~> 10.3'
|
23
|
+
s.add_dependency 'rack-ssl-enforcer', '~> 0.2'
|
24
|
+
s.add_dependency 'mercenary', '~> 0.3'
|
25
|
+
s.add_dependency 'safe_yaml', '~> 1.0'
|
26
|
+
s.add_dependency 'colorator', '~> 1.0'
|
27
|
+
s.add_dependency 'activesupport', '~> 4.0'
|
28
|
+
s.add_development_dependency 'rspec', '~> 3.1'
|
29
|
+
s.add_development_dependency 'rack-test', '~> 0.6'
|
30
|
+
s.add_development_dependency 'webmock', '~> 1.2 '
|
31
|
+
s.add_development_dependency 'pry', '~> 0.10'
|
32
|
+
s.add_development_dependency 'rubocop', '~> 0.35'
|
31
33
|
end
|
data/lib/jekyll-auth.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
1
|
+
require "sinatra-index"
|
2
|
+
require "sinatra_auth_github"
|
3
|
+
require "dotenv"
|
4
|
+
require "safe_yaml"
|
5
|
+
require "colorator"
|
6
|
+
require "mkmf"
|
7
|
+
require_relative "jekyll_auth/version"
|
8
|
+
require_relative "jekyll_auth/helpers"
|
9
|
+
require_relative "jekyll_auth/config"
|
10
|
+
require_relative "jekyll_auth/auth_site"
|
11
|
+
require_relative "jekyll_auth/jekyll_site"
|
12
|
+
require_relative "jekyll_auth/config_error"
|
13
|
+
require_relative "jekyll_auth/commands"
|
14
14
|
|
15
15
|
Dotenv.load
|
16
16
|
|
@@ -1,21 +1,16 @@
|
|
1
1
|
class JekyllAuth
|
2
2
|
class AuthSite < Sinatra::Base
|
3
|
-
|
4
3
|
configure :production do
|
5
|
-
require
|
4
|
+
require "rack-ssl-enforcer"
|
6
5
|
use Rack::SslEnforcer if JekyllAuth.ssl?
|
7
6
|
end
|
8
7
|
|
9
|
-
use Rack::Session::Cookie,
|
10
|
-
|
11
|
-
:secret => ENV['SESSION_SECRET'] || SecureRandom.hex
|
12
|
-
}
|
8
|
+
use Rack::Session::Cookie, :http_only => true,
|
9
|
+
:secret => ENV["SESSION_SECRET"] || SecureRandom.hex
|
13
10
|
|
14
|
-
set :github_options,
|
15
|
-
:scopes => 'read:org'
|
16
|
-
}
|
11
|
+
set :github_options, :scopes => "read:org"
|
17
12
|
|
18
|
-
ENV[
|
13
|
+
ENV["WARDEN_GITHUB_VERIFIER_SECRET"] ||= SecureRandom.hex
|
19
14
|
register Sinatra::Auth::Github
|
20
15
|
|
21
16
|
use Rack::Logger
|
@@ -29,19 +24,19 @@ class JekyllAuth
|
|
29
24
|
|
30
25
|
case authentication_strategy
|
31
26
|
when :team
|
32
|
-
github_team_authenticate! ENV[
|
27
|
+
github_team_authenticate! ENV["GITHUB_TEAM_ID"]
|
33
28
|
when :teams
|
34
|
-
github_teams_authenticate! ENV[
|
29
|
+
github_teams_authenticate! ENV["GITHUB_TEAM_IDS"].split(",")
|
35
30
|
when :org
|
36
|
-
github_organization_authenticate! ENV[
|
31
|
+
github_organization_authenticate! ENV["GITHUB_ORG_NAME"]
|
37
32
|
else
|
38
33
|
raise JekyllAuth::ConfigError
|
39
34
|
end
|
40
35
|
end
|
41
36
|
|
42
|
-
get
|
37
|
+
get "/logout" do
|
43
38
|
logout!
|
44
|
-
redirect
|
39
|
+
redirect "/"
|
45
40
|
end
|
46
41
|
end
|
47
42
|
end
|
data/lib/jekyll_auth/commands.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
class JekyllAuth
|
2
2
|
class Commands
|
3
|
-
|
4
|
-
|
5
|
-
VARS = %w{client_id client_secret team_id org_name}
|
3
|
+
FILES = %w(Rakefile config.ru .gitignore .env).freeze
|
4
|
+
VARS = %w(client_id client_secret team_id org_name).freeze
|
6
5
|
|
7
6
|
def self.source
|
8
|
-
@source ||= File.expand_path(
|
7
|
+
@source ||= File.expand_path("../../templates", File.dirname(__FILE__))
|
9
8
|
end
|
10
9
|
|
11
10
|
def self.destination
|
@@ -13,14 +12,14 @@ class JekyllAuth
|
|
13
12
|
end
|
14
13
|
|
15
14
|
def self.changed?
|
16
|
-
execute_command("git", "status", destination, "--porcelain").
|
15
|
+
!execute_command("git", "status", destination, "--porcelain").empty?
|
17
16
|
rescue
|
18
17
|
false
|
19
18
|
end
|
20
19
|
|
21
20
|
def self.execute_command(*args)
|
22
21
|
output, status = Open3.capture2e(*args)
|
23
|
-
raise "Command `#{args.join(" ")}` failed: #{output}"
|
22
|
+
raise "Command `#{args.join(" ")}` failed: #{output}" unless status.exitstatus.zero?
|
24
23
|
output
|
25
24
|
end
|
26
25
|
|
@@ -44,7 +43,7 @@ class JekyllAuth
|
|
44
43
|
end
|
45
44
|
|
46
45
|
def self.env_var_set?(var)
|
47
|
-
!
|
46
|
+
!ENV[var].to_s.blank?
|
48
47
|
end
|
49
48
|
|
50
49
|
def self.init_repo
|
@@ -61,7 +60,7 @@ class JekyllAuth
|
|
61
60
|
|
62
61
|
def self.heroku_remote_set?
|
63
62
|
remotes = execute_command "git", "remote", "-v"
|
64
|
-
!!(remotes =~
|
63
|
+
!!(remotes =~ %r!^heroku\s!)
|
65
64
|
end
|
66
65
|
|
67
66
|
def self.configure_heroku(options)
|
data/lib/jekyll_auth/config.rb
CHANGED
@@ -13,11 +13,11 @@ class JekyllAuth
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.whitelist
|
16
|
-
whitelist = JekyllAuth
|
16
|
+
whitelist = JekyllAuth.config["whitelist"]
|
17
17
|
Regexp.new(whitelist.join("|")) unless whitelist.nil?
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.ssl?
|
21
|
-
!!JekyllAuth
|
21
|
+
!!JekyllAuth.config["ssl"]
|
22
22
|
end
|
23
23
|
end
|
data/lib/jekyll_auth/helpers.rb
CHANGED
@@ -6,11 +6,11 @@ class JekyllAuth
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def authentication_strategy
|
9
|
-
if !ENV[
|
9
|
+
if !ENV["GITHUB_TEAM_ID"].to_s.blank?
|
10
10
|
:team
|
11
|
-
elsif !ENV[
|
11
|
+
elsif !ENV["GITHUB_TEAM_IDS"].to_s.blank?
|
12
12
|
:teams
|
13
|
-
elsif !ENV[
|
13
|
+
elsif !ENV["GITHUB_ORG_NAME"].to_s.blank?
|
14
14
|
:org
|
15
15
|
end
|
16
16
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
class JekyllAuth
|
2
2
|
class JekyllSite < Sinatra::Base
|
3
|
-
|
4
3
|
register Sinatra::Index
|
5
|
-
set :public_folder, File.expand_path(
|
6
|
-
use_static_index
|
4
|
+
set :public_folder, File.expand_path("_site", Dir.pwd)
|
5
|
+
use_static_index "index.html"
|
7
6
|
|
8
7
|
not_found do
|
9
8
|
status 404
|
10
|
-
four_oh_four = File.expand_path(
|
11
|
-
File.read(four_oh_four) if File.
|
9
|
+
four_oh_four = File.expand_path("_site/404.html", Dir.pwd)
|
10
|
+
File.read(four_oh_four) if File.exist?(four_oh_four)
|
12
11
|
end
|
13
12
|
end
|
14
13
|
end
|
data/lib/jekyll_auth/version.rb
CHANGED
data/script/cibuild
CHANGED
@@ -9,34 +9,32 @@ describe "logged in user" do
|
|
9
9
|
|
10
10
|
before(:each) do
|
11
11
|
setup_tmp_dir
|
12
|
-
@user = make_user(
|
12
|
+
@user = make_user("login" => "benbaltertest")
|
13
13
|
login_as @user
|
14
14
|
|
15
|
-
ENV[
|
16
|
-
|
17
|
-
stub_request(:get, "https://api.github.com/orgs/#{ENV["GITHUB_ORG_NAME"]}/members/benbaltertest")
|
18
|
-
|
15
|
+
ENV["GITHUB_ORG_NAME"] = "balter-test-org"
|
16
|
+
|
17
|
+
stub_request(:get, "https://api.github.com/orgs/#{ENV["GITHUB_ORG_NAME"]}/members/benbaltertest")
|
18
|
+
.to_return(:status => 200)
|
19
19
|
end
|
20
20
|
|
21
21
|
it "shows the securocat when github returns an oauth error" do
|
22
22
|
get "/auth/github/callback?error=redirect_uri_mismatch"
|
23
|
-
expect(last_response.body).to match(%r
|
23
|
+
expect(last_response.body).to match(%r!securocat\.png!)
|
24
24
|
end
|
25
25
|
|
26
26
|
it "logs the user out" do
|
27
27
|
get "/logout"
|
28
28
|
expect(last_response.status).to eql(302)
|
29
|
-
expect(last_response.headers[
|
29
|
+
expect(last_response.headers["Location"]).to eql("http://example.org/")
|
30
30
|
|
31
31
|
get "/"
|
32
32
|
expect(last_response.status).to eql(302)
|
33
|
-
expect(last_response.headers[
|
33
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
34
34
|
end
|
35
|
-
|
36
35
|
end
|
37
36
|
|
38
37
|
describe "logged out user" do
|
39
|
-
|
40
38
|
include Rack::Test::Methods
|
41
39
|
|
42
40
|
def app
|
@@ -44,33 +42,33 @@ describe "logged out user" do
|
|
44
42
|
end
|
45
43
|
|
46
44
|
before do
|
47
|
-
ENV[
|
45
|
+
ENV["GITHUB_ORG_NAME"] = "balter-test-org"
|
48
46
|
end
|
49
47
|
|
50
48
|
it "doesn't let you view indexes" do
|
51
49
|
get "/"
|
52
50
|
expect(last_response.status).to eql(302)
|
53
|
-
expect(last_response.headers[
|
51
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
54
52
|
|
55
53
|
get "/some_dir"
|
56
54
|
expect(last_response.status).to eql(302)
|
57
|
-
expect(last_response.headers[
|
55
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
58
56
|
end
|
59
57
|
|
60
58
|
it "doesn't let you view files" do
|
61
59
|
get "/index.html"
|
62
60
|
expect(last_response.status).to eql(302)
|
63
|
-
expect(last_response.headers[
|
61
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
64
62
|
|
65
63
|
get "/some_dir/index.html"
|
66
64
|
expect(last_response.status).to eql(302)
|
67
|
-
expect(last_response.headers[
|
65
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
68
66
|
end
|
69
67
|
|
70
68
|
it "refuses to serve the site without an authentication strategy" do
|
71
69
|
ENV["GITHUB_ORG_NAME"] = nil
|
72
70
|
ENV["GITHUB_TEAM_ID"] = nil
|
73
71
|
ENV["GITHUB_TEAMS_ID"] = nil
|
74
|
-
expect{get "/"}.to raise_error(JekyllAuth::ConfigError)
|
72
|
+
expect { get "/" }.to raise_error(JekyllAuth::ConfigError)
|
75
73
|
end
|
76
74
|
end
|
@@ -6,23 +6,22 @@ describe "bin" do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
it "spits out the help do" do
|
9
|
-
env = { "GITHUB_TOKEN" => nil}
|
9
|
+
env = { "GITHUB_TOKEN" => nil }
|
10
10
|
output = execute_bin(env, "--help")
|
11
|
-
expect(output).to match(%r
|
11
|
+
expect(output).to match(%r!A simple way to use Github OAuth to serve a protected jekyll site to your GitHub organization!)
|
12
12
|
end
|
13
13
|
|
14
14
|
describe "team id" do
|
15
|
-
|
16
15
|
it "errors if no token is given" do
|
17
|
-
env = { "GITHUB_TOKEN" => nil}
|
18
|
-
expect{execute_bin(env, "team_id", "--org", "balter-test-org", "--team", "1")}.to raise_error(RuntimeError)
|
19
|
-
|
16
|
+
env = { "GITHUB_TOKEN" => nil }
|
17
|
+
expect { execute_bin(env, "team_id", "--org", "balter-test-org", "--team", "1") }.to raise_error(RuntimeError)
|
18
|
+
.with_message(%r!prefix the jekyll-auth command with GITHUB_TOKEN!)
|
20
19
|
end
|
21
20
|
|
22
21
|
it "errors if no team_id or org_name is given" do
|
23
|
-
env = { "GITHUB_TOKEN" => "1234"}
|
24
|
-
expect{execute_bin(env, "team_id")}.to raise_error(RuntimeError)
|
25
|
-
|
22
|
+
env = { "GITHUB_TOKEN" => "1234" }
|
23
|
+
expect { execute_bin(env, "team_id") }.to raise_error(RuntimeError)
|
24
|
+
.with_message(%r!An org name and team ID are required!)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
@@ -30,7 +29,7 @@ describe "bin" do
|
|
30
29
|
`git init`
|
31
30
|
`git add .`
|
32
31
|
`git commit -m 'initial commit'`
|
33
|
-
execute_bin({"RACK_ENV" => "TEST"}, "new")
|
32
|
+
execute_bin({ "RACK_ENV" => "TEST" }, "new")
|
34
33
|
expect(File).to exist("#{tmp_dir}/config.ru")
|
35
34
|
expect(File).to exist("#{tmp_dir}/Rakefile")
|
36
35
|
expect(File).to exist("#{tmp_dir}/.gitignore")
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "commands" do
|
4
|
-
|
5
4
|
before do
|
6
5
|
setup_tmp_dir
|
7
6
|
end
|
@@ -16,12 +15,12 @@ describe "commands" do
|
|
16
15
|
end
|
17
16
|
|
18
17
|
it "should execute a command" do
|
19
|
-
expect(JekyllAuth::Commands.execute_command("ls")).to match(
|
18
|
+
expect(JekyllAuth::Commands.execute_command("ls")).to match(%r!index\.html!)
|
20
19
|
end
|
21
20
|
|
22
21
|
it "should retrieve a team's ID" do
|
23
|
-
stub_request(:get, "https://api.github.com/orgs/batler-test-org/teams?per_page=100")
|
24
|
-
|
22
|
+
stub_request(:get, "https://api.github.com/orgs/batler-test-org/teams?per_page=100")
|
23
|
+
.to_return(:status => 204, :body => [{ :slug => "test-team", :id => 1 }])
|
25
24
|
expect(JekyllAuth::Commands.team_id("batler-test-org", "test-team")).to eql(1)
|
26
25
|
end
|
27
26
|
|
@@ -71,6 +70,6 @@ describe "commands" do
|
|
71
70
|
`git add foo.md`
|
72
71
|
JekyllAuth::Commands.initial_commit
|
73
72
|
output = JekyllAuth::Commands.execute_command "git", "log"
|
74
|
-
expect(output).to match(
|
73
|
+
expect(output).to match(%r!\[Jekyll Auth\] Initial setup!)
|
75
74
|
end
|
76
75
|
end
|
data/spec/jekyll_auth_spec.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "JekyllAuth" do
|
4
|
-
|
5
4
|
before(:each) do
|
6
5
|
setup_tmp_dir
|
7
|
-
JekyllAuth.instance_variable_set("@config",nil)
|
6
|
+
JekyllAuth.instance_variable_set("@config", nil)
|
8
7
|
end
|
9
8
|
|
10
9
|
it "should know the config file path" do
|
@@ -23,7 +22,7 @@ describe "JekyllAuth" do
|
|
23
22
|
|
24
23
|
it "should return the config hash if the config files contains jekyll_auth" do
|
25
24
|
File.write(JekyllAuth.config_file, "jekyll_auth:\n ssl: true\n whitelist:\n - drafts?\n")
|
26
|
-
expect(JekyllAuth.config).to eql(
|
25
|
+
expect(JekyllAuth.config).to eql("ssl" => true, "whitelist" => ["drafts?"])
|
27
26
|
end
|
28
27
|
|
29
28
|
it "should disable ssl by default" do
|
@@ -42,6 +41,6 @@ describe "JekyllAuth" do
|
|
42
41
|
|
43
42
|
it "should parse the whitelist" do
|
44
43
|
File.write(JekyllAuth.config_file, "jekyll_auth:\n whitelist:\n - drafts?\n")
|
45
|
-
expect(JekyllAuth.whitelist).to eql(
|
44
|
+
expect(JekyllAuth.whitelist).to eql(%r!drafts?!)
|
46
45
|
end
|
47
46
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
require "bundler/setup"
|
2
|
-
require
|
2
|
+
require "fileutils"
|
3
3
|
|
4
|
-
ENV[
|
5
|
-
|
4
|
+
ENV["RACK_ENV"] = "test"
|
5
|
+
$LOAD_PATH.push File.join(File.dirname(__FILE__), "..", "lib")
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
7
|
+
require "rack/test"
|
8
|
+
require "sinatra/auth/github"
|
9
|
+
require "sinatra/auth/github/test/test_helper"
|
10
|
+
require "webmock/rspec"
|
11
|
+
require "dotenv"
|
12
|
+
require "open3"
|
13
13
|
|
14
14
|
def base_dir
|
15
15
|
File.expand_path "../", File.dirname(__FILE__)
|
@@ -50,6 +50,8 @@ def execute_bin(env, *args)
|
|
50
50
|
end
|
51
51
|
|
52
52
|
Dotenv.load
|
53
|
+
ENV["GITHUB_CLIENT_ID"] ||= "IGNORE"
|
54
|
+
ENV["GITHUB_CLIENT_SECRET"] ||= "IGNORE"
|
53
55
|
setup_tmp_dir
|
54
56
|
|
55
57
|
require_relative "../lib/jekyll-auth"
|
data/templates/Rakefile
CHANGED
data/templates/config.ru
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Balter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '3.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: '3.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sinatra-index
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +142,28 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0
|
145
|
+
version: '1.0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: activesupport
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '4.0'
|
146
160
|
type: :runtime
|
147
161
|
prerelease: false
|
148
162
|
version_requirements: !ruby/object:Gem::Requirement
|
149
163
|
requirements:
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
|
-
version: '0
|
166
|
+
version: '4.0'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: rspec
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,6 +220,20 @@ dependencies:
|
|
206
220
|
- - "~>"
|
207
221
|
- !ruby/object:Gem::Version
|
208
222
|
version: '0.10'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: rubocop
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0.35'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - "~>"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0.35'
|
209
237
|
description: A simple way to use GitHub OAuth to serve a protected jekyll site to
|
210
238
|
your GitHub organization.
|
211
239
|
email: ben@balter.com
|
@@ -215,6 +243,7 @@ extensions: []
|
|
215
243
|
extra_rdoc_files: []
|
216
244
|
files:
|
217
245
|
- ".gitignore"
|
246
|
+
- ".rubocop.yml"
|
218
247
|
- ".travis.yml"
|
219
248
|
- Gemfile
|
220
249
|
- README.md
|
@@ -268,7 +297,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
268
297
|
version: '0'
|
269
298
|
requirements: []
|
270
299
|
rubyforge_project:
|
271
|
-
rubygems_version: 2.
|
300
|
+
rubygems_version: 2.6.7
|
272
301
|
signing_key:
|
273
302
|
specification_version: 4
|
274
303
|
summary: A simple way to use GitHub OAuth to serve a protected jekyll site to your
|
@@ -281,4 +310,3 @@ test_files:
|
|
281
310
|
- spec/jekyll_auth_jekyll_site_spec.rb
|
282
311
|
- spec/jekyll_auth_spec.rb
|
283
312
|
- spec/spec_helper.rb
|
284
|
-
has_rdoc:
|