jekyll-auth 1.0.2 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/CODEOWNERS +3 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- data/.github/config.yml +23 -0
- data/.github/funding.yml +1 -0
- data/.github/no-response.yml +15 -0
- data/.github/release-drafter.yml +4 -0
- data/.github/settings.yml +33 -0
- data/.github/stale.yml +29 -0
- data/.rubocop.yml +28 -0
- data/.travis.yml +5 -1
- data/Gemfile +2 -0
- data/Rakefile +9 -7
- data/bin/jekyll-auth +36 -36
- data/docs/CODE_OF_CONDUCT.md +46 -0
- data/docs/CONTRIBUTING.md +88 -0
- data/docs/README.md +33 -0
- data/docs/SECURITY.md +3 -0
- data/docs/_config.yml +2 -0
- data/docs/configuring.md +36 -0
- data/docs/getting-started.md +63 -0
- data/docs/running-locally.md +24 -0
- data/docs/troubleshooting.md +31 -0
- data/jekyll-auth.gemspec +22 -15
- data/lib/jekyll-auth.rb +16 -13
- data/lib/jekyll_auth/auth_site.rb +12 -15
- data/lib/jekyll_auth/commands.rb +12 -9
- data/lib/jekyll_auth/config.rb +15 -8
- data/lib/jekyll_auth/config_error.rb +3 -2
- data/lib/jekyll_auth/helpers.rb +6 -3
- data/lib/jekyll_auth/jekyll_site.rb +6 -5
- data/lib/jekyll_auth/sinatra/auth/github.rb +8 -4
- data/lib/jekyll_auth/version.rb +3 -1
- data/script/cibuild +5 -0
- data/spec/jekyll_auth_auth_site_spec.rb +17 -17
- data/spec/jekyll_auth_bin_spec.rb +12 -11
- data/spec/jekyll_auth_commands_spec.rb +6 -5
- data/spec/jekyll_auth_helpers_spec.rb +5 -4
- data/spec/jekyll_auth_jekyll_site_spec.rb +2 -1
- data/spec/jekyll_auth_spec.rb +5 -4
- data/spec/spec_helper.rb +14 -9
- data/templates/.gitignore +0 -1
- data/templates/Rakefile +2 -0
- data/templates/config.ru +2 -0
- metadata +150 -45
- data/README.md +0 -149
data/lib/jekyll_auth/config.rb
CHANGED
@@ -1,23 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class JekyllAuth
|
2
4
|
def self.config_file
|
3
5
|
File.join(Dir.pwd, "_config.yml")
|
4
6
|
end
|
5
7
|
|
8
|
+
def self.jekyll_config
|
9
|
+
@config ||= YAML.safe_load_file(config_file)
|
10
|
+
rescue StandardError
|
11
|
+
{}
|
12
|
+
end
|
13
|
+
|
6
14
|
def self.config
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
15
|
+
jekyll_config.fetch("jekyll_auth", {})
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.destination
|
19
|
+
jekyll_config.fetch("destination", File.expand_path("_site", Dir.pwd))
|
13
20
|
end
|
14
21
|
|
15
22
|
def self.whitelist
|
16
|
-
whitelist =
|
23
|
+
whitelist = config["whitelist"]
|
17
24
|
Regexp.new(whitelist.join("|")) unless whitelist.nil?
|
18
25
|
end
|
19
26
|
|
20
27
|
def self.ssl?
|
21
|
-
!!
|
28
|
+
!!config["ssl"]
|
22
29
|
end
|
23
30
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
|
-
class ConfigError < SecurityError
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
class JekyllAuth
|
4
|
+
class ConfigError < RuntimeError
|
4
5
|
def message
|
5
6
|
"Jekyll Auth is refusing to serve your site because your oauth credentials are not properly configured."
|
6
7
|
end
|
data/lib/jekyll_auth/helpers.rb
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class JekyllAuth
|
2
4
|
module Helpers
|
3
5
|
def whitelisted?
|
4
6
|
return true if request.path_info == "/logout"
|
7
|
+
|
5
8
|
!!(JekyllAuth.whitelist && JekyllAuth.whitelist.match(request.path_info))
|
6
9
|
end
|
7
10
|
|
8
11
|
def authentication_strategy
|
9
|
-
if !ENV[
|
12
|
+
if !ENV["GITHUB_TEAM_ID"].to_s.blank?
|
10
13
|
:team
|
11
|
-
elsif !ENV[
|
14
|
+
elsif !ENV["GITHUB_TEAM_IDS"].to_s.blank?
|
12
15
|
:teams
|
13
|
-
elsif !ENV[
|
16
|
+
elsif !ENV["GITHUB_ORG_NAME"].to_s.blank?
|
14
17
|
:org
|
15
18
|
end
|
16
19
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class JekyllAuth
|
2
4
|
class JekyllSite < Sinatra::Base
|
3
|
-
|
4
5
|
register Sinatra::Index
|
5
|
-
set :public_folder, File.expand_path(
|
6
|
-
use_static_index
|
6
|
+
set :public_folder, File.expand_path(JekyllAuth.destination, Dir.pwd)
|
7
|
+
use_static_index "index.html"
|
7
8
|
|
8
9
|
not_found do
|
9
10
|
status 404
|
10
|
-
four_oh_four = File.expand_path(
|
11
|
-
File.read(four_oh_four) if File.
|
11
|
+
four_oh_four = File.expand_path(settings.public_folder + "/404.html", Dir.pwd)
|
12
|
+
File.read(four_oh_four) if File.exist?(four_oh_four)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -1,10 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sinatra
|
2
4
|
module Auth
|
3
5
|
module Github
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
6
|
+
module Helpers
|
7
|
+
# Like the native github_team_authenticate! but accepts an array of team ids
|
8
|
+
def github_teams_authenticate!(teams)
|
9
|
+
authenticate!
|
10
|
+
halt([401, "Unauthorized User"]) unless teams.any? { |team_id| github_team_access?(team_id) }
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
data/lib/jekyll_auth/version.rb
CHANGED
data/script/cibuild
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe "logged in user" do
|
@@ -9,34 +11,32 @@ describe "logged in user" do
|
|
9
11
|
|
10
12
|
before(:each) do
|
11
13
|
setup_tmp_dir
|
12
|
-
@user = make_user(
|
14
|
+
@user = make_user("login" => "benbaltertest")
|
13
15
|
login_as @user
|
14
16
|
|
15
|
-
ENV[
|
16
|
-
|
17
|
-
stub_request(:get, "https://api.github.com/orgs/#{ENV["
|
18
|
-
|
17
|
+
ENV["GITHUB_ORG_NAME"] = "balter-test-org"
|
18
|
+
|
19
|
+
stub_request(:get, "https://api.github.com/orgs/#{ENV["GITHUB_ORG_NAME"]}/members/benbaltertest")
|
20
|
+
.to_return(:status => 200)
|
19
21
|
end
|
20
22
|
|
21
23
|
it "shows the securocat when github returns an oauth error" do
|
22
24
|
get "/auth/github/callback?error=redirect_uri_mismatch"
|
23
|
-
expect(last_response.body).to match(%r
|
25
|
+
expect(last_response.body).to match(%r!securocat\.png!)
|
24
26
|
end
|
25
27
|
|
26
28
|
it "logs the user out" do
|
27
29
|
get "/logout"
|
28
30
|
expect(last_response.status).to eql(302)
|
29
|
-
expect(last_response.headers[
|
31
|
+
expect(last_response.headers["Location"]).to eql("http://example.org/")
|
30
32
|
|
31
33
|
get "/"
|
32
34
|
expect(last_response.status).to eql(302)
|
33
|
-
expect(last_response.headers[
|
35
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
34
36
|
end
|
35
|
-
|
36
37
|
end
|
37
38
|
|
38
39
|
describe "logged out user" do
|
39
|
-
|
40
40
|
include Rack::Test::Methods
|
41
41
|
|
42
42
|
def app
|
@@ -44,33 +44,33 @@ describe "logged out user" do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
before do
|
47
|
-
ENV[
|
47
|
+
ENV["GITHUB_ORG_NAME"] = "balter-test-org"
|
48
48
|
end
|
49
49
|
|
50
50
|
it "doesn't let you view indexes" do
|
51
51
|
get "/"
|
52
52
|
expect(last_response.status).to eql(302)
|
53
|
-
expect(last_response.headers[
|
53
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
54
54
|
|
55
55
|
get "/some_dir"
|
56
56
|
expect(last_response.status).to eql(302)
|
57
|
-
expect(last_response.headers[
|
57
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
58
58
|
end
|
59
59
|
|
60
60
|
it "doesn't let you view files" do
|
61
61
|
get "/index.html"
|
62
62
|
expect(last_response.status).to eql(302)
|
63
|
-
expect(last_response.headers[
|
63
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
64
64
|
|
65
65
|
get "/some_dir/index.html"
|
66
66
|
expect(last_response.status).to eql(302)
|
67
|
-
expect(last_response.headers[
|
67
|
+
expect(last_response.headers["Location"]).to match(%r!^https://github\.com/login/oauth/authorize!)
|
68
68
|
end
|
69
69
|
|
70
70
|
it "refuses to serve the site without an authentication strategy" do
|
71
|
-
ENV["
|
71
|
+
ENV["GITHUB_ORG_NAME"] = nil
|
72
72
|
ENV["GITHUB_TEAM_ID"] = nil
|
73
73
|
ENV["GITHUB_TEAMS_ID"] = nil
|
74
|
-
expect{get "/"}.to raise_error(JekyllAuth::ConfigError)
|
74
|
+
expect { get "/" }.to raise_error(JekyllAuth::ConfigError)
|
75
75
|
end
|
76
76
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe "bin" do
|
@@ -6,23 +8,22 @@ describe "bin" do
|
|
6
8
|
end
|
7
9
|
|
8
10
|
it "spits out the help do" do
|
9
|
-
env = { "GITHUB_TOKEN" => nil}
|
11
|
+
env = { "GITHUB_TOKEN" => nil }
|
10
12
|
output = execute_bin(env, "--help")
|
11
|
-
expect(output).to match(%r
|
13
|
+
expect(output).to match(%r!A simple way to use Github OAuth to serve a protected jekyll site to your GitHub organization!)
|
12
14
|
end
|
13
15
|
|
14
16
|
describe "team id" do
|
15
|
-
|
16
17
|
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
|
-
|
18
|
+
env = { "GITHUB_TOKEN" => nil }
|
19
|
+
expect { execute_bin(env, "team_id", "--org", "balter-test-org", "--team", "1") }.to raise_error(RuntimeError)
|
20
|
+
.with_message(%r!prefix the jekyll-auth command with GITHUB_TOKEN!)
|
20
21
|
end
|
21
22
|
|
22
|
-
it "errors if no team_id or
|
23
|
-
env = { "GITHUB_TOKEN" => "1234"}
|
24
|
-
expect{execute_bin(env, "team_id")}.to raise_error(RuntimeError)
|
25
|
-
|
23
|
+
it "errors if no team_id or org_name is given" do
|
24
|
+
env = { "GITHUB_TOKEN" => "1234" }
|
25
|
+
expect { execute_bin(env, "team_id") }.to raise_error(RuntimeError)
|
26
|
+
.with_message(%r!An org name and team ID are required!)
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -30,7 +31,7 @@ describe "bin" do
|
|
30
31
|
`git init`
|
31
32
|
`git add .`
|
32
33
|
`git commit -m 'initial commit'`
|
33
|
-
execute_bin({"RACK_ENV" => "TEST"}, "new")
|
34
|
+
execute_bin({ "RACK_ENV" => "TEST" }, "new")
|
34
35
|
expect(File).to exist("#{tmp_dir}/config.ru")
|
35
36
|
expect(File).to exist("#{tmp_dir}/Rakefile")
|
36
37
|
expect(File).to exist("#{tmp_dir}/.gitignore")
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe "commands" do
|
4
|
-
|
5
6
|
before do
|
6
7
|
setup_tmp_dir
|
7
8
|
end
|
@@ -16,12 +17,12 @@ describe "commands" do
|
|
16
17
|
end
|
17
18
|
|
18
19
|
it "should execute a command" do
|
19
|
-
expect(JekyllAuth::Commands.execute_command("ls")).to match(
|
20
|
+
expect(JekyllAuth::Commands.execute_command("ls")).to match(%r!index\.html!)
|
20
21
|
end
|
21
22
|
|
22
23
|
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
|
-
|
24
|
+
stub_request(:get, "https://api.github.com/orgs/batler-test-org/teams?per_page=100")
|
25
|
+
.to_return(:status => 204, :body => [{ :slug => "test-team", :id => 1 }])
|
25
26
|
expect(JekyllAuth::Commands.team_id("batler-test-org", "test-team")).to eql(1)
|
26
27
|
end
|
27
28
|
|
@@ -71,6 +72,6 @@ describe "commands" do
|
|
71
72
|
`git add foo.md`
|
72
73
|
JekyllAuth::Commands.initial_commit
|
73
74
|
output = JekyllAuth::Commands.execute_command "git", "log"
|
74
|
-
expect(output).to match(
|
75
|
+
expect(output).to match(%r!\[Jekyll Auth\] Initial setup!)
|
75
76
|
end
|
76
77
|
end
|
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe "strategies" do
|
4
|
-
|
5
6
|
class TestHelper
|
6
7
|
include JekyllAuth::Helpers
|
7
8
|
|
8
|
-
def initialize(path=nil)
|
9
|
+
def initialize(path = nil)
|
9
10
|
@path = path
|
10
11
|
end
|
11
12
|
|
@@ -17,7 +18,7 @@ describe "strategies" do
|
|
17
18
|
before(:each) do
|
18
19
|
JekyllAuth.instance_variable_set("@config", nil)
|
19
20
|
@helper = TestHelper.new
|
20
|
-
ENV["
|
21
|
+
ENV["GITHUB_ORG_NAME"] = nil
|
21
22
|
ENV["GITHUB_TEAM_ID"] = nil
|
22
23
|
ENV["GITHUB_TEAMS_ID"] = nil
|
23
24
|
end
|
@@ -27,7 +28,7 @@ describe "strategies" do
|
|
27
28
|
end
|
28
29
|
|
29
30
|
it "should detect the org strategy" do
|
30
|
-
with_env("
|
31
|
+
with_env("GITHUB_ORG_NAME", "some_org") do
|
31
32
|
expect(@helper.authentication_strategy).to eql(:org)
|
32
33
|
end
|
33
34
|
end
|
data/spec/jekyll_auth_spec.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe "JekyllAuth" do
|
4
|
-
|
5
6
|
before(:each) do
|
6
7
|
setup_tmp_dir
|
7
|
-
JekyllAuth.instance_variable_set("@config",nil)
|
8
|
+
JekyllAuth.instance_variable_set("@config", nil)
|
8
9
|
end
|
9
10
|
|
10
11
|
it "should know the config file path" do
|
@@ -23,7 +24,7 @@ describe "JekyllAuth" do
|
|
23
24
|
|
24
25
|
it "should return the config hash if the config files contains jekyll_auth" do
|
25
26
|
File.write(JekyllAuth.config_file, "jekyll_auth:\n ssl: true\n whitelist:\n - drafts?\n")
|
26
|
-
expect(JekyllAuth.config).to eql(
|
27
|
+
expect(JekyllAuth.config).to eql("ssl" => true, "whitelist" => ["drafts?"])
|
27
28
|
end
|
28
29
|
|
29
30
|
it "should disable ssl by default" do
|
@@ -42,6 +43,6 @@ describe "JekyllAuth" do
|
|
42
43
|
|
43
44
|
it "should parse the whitelist" do
|
44
45
|
File.write(JekyllAuth.config_file, "jekyll_auth:\n whitelist:\n - drafts?\n")
|
45
|
-
expect(JekyllAuth.whitelist).to eql(
|
46
|
+
expect(JekyllAuth.whitelist).to eql(%r!drafts?!)
|
46
47
|
end
|
47
48
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "bundler/setup"
|
2
|
-
require
|
4
|
+
require "fileutils"
|
3
5
|
|
4
|
-
ENV[
|
5
|
-
|
6
|
+
ENV["RACK_ENV"] = "test"
|
7
|
+
$LOAD_PATH.push File.join(File.dirname(__FILE__), "..", "lib")
|
6
8
|
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
9
|
+
require "rack/test"
|
10
|
+
require "sinatra/auth/github"
|
11
|
+
require "sinatra/auth/github/test/test_helper"
|
12
|
+
require "webmock/rspec"
|
13
|
+
require "dotenv"
|
14
|
+
require "open3"
|
13
15
|
|
14
16
|
def base_dir
|
15
17
|
File.expand_path "../", File.dirname(__FILE__)
|
@@ -46,10 +48,13 @@ end
|
|
46
48
|
def execute_bin(env, *args)
|
47
49
|
output, status = Open3.capture2e(env, bin_path, *args)
|
48
50
|
raise "Command `#{bin_path} #{args.join(" ")}` failed: #{output}" if status != 0
|
51
|
+
|
49
52
|
output
|
50
53
|
end
|
51
54
|
|
52
55
|
Dotenv.load
|
56
|
+
ENV["GITHUB_CLIENT_ID"] ||= "IGNORE"
|
57
|
+
ENV["GITHUB_CLIENT_SECRET"] ||= "IGNORE"
|
53
58
|
setup_tmp_dir
|
54
59
|
|
55
60
|
require_relative "../lib/jekyll-auth"
|
data/templates/.gitignore
CHANGED
data/templates/Rakefile
CHANGED