-
-
Notifications
You must be signed in to change notification settings - Fork 176
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: move basic auth code in from pact-broker-docker
- Loading branch information
Showing
11 changed files
with
578 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
source "https://rubygems.org" | ||
|
||
gem "pact_broker" | ||
gem "pg" | ||
gem "pact_broker", path: "../.." | ||
gem "sqlite3" | ||
gem "thin" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
basic_auth_username: "user" | ||
basic_auth_password: "pass" | ||
basic_auth_read_only_username: "rouser" | ||
basic_auth_read_only_password: "ropass" | ||
database_url: sqlite:////tmp/pact_broker.sqlite3 |
62 changes: 62 additions & 0 deletions
62
lib/pact_broker/api/authorization/resource_access_policy.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
require "pact_broker/api/authorization/resource_access_rules" | ||
|
||
module PactBroker | ||
module Api | ||
module Authorization | ||
class ResourceAccessPolicy | ||
READ_METHODS = %w{GET OPTIONS HEAD}.freeze | ||
ALL_METHODS = %w{GET POST PUT PATCH DELETE HEAD OPTIONS}.freeze | ||
POST = "POST".freeze | ||
|
||
ALL_PATHS = %r{.*}.freeze | ||
PACT_BADGE_PATH = %r{^/pacts/provider/[^/]+/consumer/.*/badge(?:\.[A-Za-z]+)?$}.freeze | ||
MATRIX_BADGE_PATH = %r{^/matrix/provider/[^/]+/latest/[^/]+/consumer/[^/]+/latest/[^/]+/badge(?:\.[A-Za-z]+)?$}.freeze | ||
HEARTBEAT_PATH = %r{^/diagnostic/status/heartbeat$}.freeze | ||
PACTS_FOR_VERIFICATION_PATH = %r{^/pacts/provider/[^/]+/for-verification$}.freeze | ||
|
||
PUBLIC = 0 | ||
READ = 1 | ||
WRITE = 2 | ||
|
||
def initialize(resource_access_rules) | ||
@resource_access_rules = resource_access_rules | ||
end | ||
|
||
def public_access_allowed?(env) | ||
resource_access_rules.access_allowed?(env, PUBLIC) | ||
end | ||
|
||
def read_access_allowed?(env) | ||
resource_access_rules.access_allowed?(env, READ) | ||
end | ||
|
||
def self.build(allow_public_read_access, allow_public_access_to_heartbeat) | ||
rules = [ | ||
[WRITE, ALL_METHODS, ALL_PATHS], | ||
[READ, READ_METHODS, ALL_PATHS], | ||
[READ, [POST], PACTS_FOR_VERIFICATION_PATH], | ||
[PUBLIC, READ_METHODS, PACT_BADGE_PATH], | ||
[PUBLIC, READ_METHODS, MATRIX_BADGE_PATH] | ||
] | ||
|
||
if allow_public_access_to_heartbeat | ||
rules.unshift([PUBLIC, READ_METHODS, HEARTBEAT_PATH]) | ||
end | ||
|
||
if allow_public_read_access | ||
rules.unshift([PUBLIC, READ_METHODS, ALL_PATHS]) | ||
rules.unshift([PUBLIC, [POST], PACTS_FOR_VERIFICATION_PATH]) | ||
end | ||
|
||
ResourceAccessPolicy.new(ResourceAccessRules.new(rules)) | ||
end | ||
|
||
private | ||
|
||
attr_reader :resource_access_rules | ||
end | ||
|
||
end | ||
end | ||
end | ||
|
40 changes: 40 additions & 0 deletions
40
lib/pact_broker/api/authorization/resource_access_rules.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
require "rack" | ||
|
||
module PactBroker | ||
module Api | ||
module Authorization | ||
class ResourceAccessRules | ||
PATH_INFO = Rack::PATH_INFO | ||
REQUEST_METHOD = Rack::REQUEST_METHOD | ||
|
||
def initialize(rules) | ||
@rules = rules | ||
end | ||
|
||
def access_allowed?(env, level) | ||
!!rules.find do | rule_level, allowed_methods, path_pattern | | ||
level_allowed?(level, rule_level) && | ||
method_allowed?(env, allowed_methods) && | ||
path_allowed?(env, path_pattern) | ||
end | ||
end | ||
|
||
private | ||
|
||
attr_reader :rules | ||
|
||
def level_allowed?(level, rule_level) | ||
level >= rule_level | ||
end | ||
|
||
def path_allowed?(env, pattern) | ||
env[PATH_INFO] =~ pattern | ||
end | ||
|
||
def method_allowed?(env, allowed_methods) | ||
allowed_methods.include?(env[REQUEST_METHOD]) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
require "rack" | ||
|
||
module PactBroker | ||
module Api | ||
module Middleware | ||
class BasicAuth | ||
def initialize(app, write_credentials, read_credentials, policy) | ||
@app = app | ||
@write_credentials = write_credentials | ||
@read_credentials = read_credentials | ||
@app_with_write_auth = build_app_with_write_auth | ||
@app_with_read_auth = build_app_with_read_auth | ||
@policy = policy | ||
end | ||
|
||
def call(env) | ||
if policy.public_access_allowed?(env) | ||
app.call(env) | ||
elsif policy.read_access_allowed?(env) | ||
app_with_read_auth.call(env) | ||
else | ||
app_with_write_auth.call(env) | ||
end | ||
end | ||
|
||
protected | ||
|
||
def write_credentials_match(*credentials) | ||
credentials == write_credentials | ||
end | ||
|
||
def read_credentials_match(*credentials) | ||
is_set(read_credentials[0]) && credentials == read_credentials | ||
end | ||
|
||
private | ||
|
||
attr_reader :app, :app_with_read_auth, :app_with_write_auth, :write_credentials, :read_credentials, :policy | ||
|
||
def build_app_with_write_auth | ||
this = self | ||
Rack::Auth::Basic.new(app, "Restricted area") do |username, password| | ||
this.write_credentials_match(username, password) | ||
end | ||
end | ||
|
||
def build_app_with_read_auth | ||
this = self | ||
Rack::Auth::Basic.new(app, "Restricted area") do |username, password| | ||
this.write_credentials_match(username, password) || this.read_credentials_match(username, password) | ||
end | ||
end | ||
|
||
def is_set(string) | ||
string && string.strip.size > 0 | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
require "pact_broker/config/runtime_configuration_logging_methods" | ||
|
||
module PactBroker | ||
module Config | ||
class BasicAuthRuntimeConfiguration < Anyway::Config | ||
include RuntimeConfigurationLoggingMethods | ||
|
||
config_name :pact_broker | ||
|
||
attr_config( | ||
basic_auth_username: nil, | ||
basic_auth_password: nil, | ||
basic_auth_read_only_username: nil, | ||
basic_auth_read_only_password: nil, | ||
allow_public_read: false, | ||
public_heartbeat: false | ||
) | ||
|
||
sensitive_values(:basic_auth_password, :basic_auth_read_only_password) | ||
|
||
def write_credentials | ||
[basic_auth_username, basic_auth_password] | ||
end | ||
|
||
def read_credentials | ||
[basic_auth_read_only_username, basic_auth_read_only_password] | ||
end | ||
|
||
def use_basic_auth? | ||
basic_auth_username && basic_auth_password != "" && basic_auth_password && basic_auth_password != "" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.