sq_auth 0.0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Rakefile +7 -0
- data/examples/client.rb +23 -0
- data/examples/server.rb +37 -0
- data/lib/sq_auth/sq_auth_access.rb +103 -0
- data/lib/sq_auth/sq_auth_client.rb +72 -0
- data/lib/sq_auth/sq_auth_helpers/sq_auth_helpers_dsl.rb +61 -0
- data/lib/sq_auth/sq_auth_helpers/sq_auth_helpers_rails.rb +39 -0
- data/lib/sq_auth/sq_auth_helpers/sq_auth_helpers_sinatra.rb +25 -0
- data/lib/sq_auth/sq_auth_integration/sq_auth_action_controller.rb +16 -0
- data/lib/sq_auth/sq_auth_integration/sq_auth_integration.rb +23 -0
- data/lib/sq_auth/sq_auth_integration/sq_auth_rack.rb +89 -0
- data/lib/sq_auth/sq_auth_integration/sq_auth_rack_protection.rb +28 -0
- data/lib/sq_auth/sq_auth_integration/sq_auth_sinatra.rb +36 -0
- data/lib/sq_auth/sq_auth_request.rb +88 -0
- data/lib/sq_auth/sq_auth_server_interface/basic_server.rb +40 -0
- data/lib/sq_auth/sq_auth_sessions.rb +16 -0
- data/lib/sq_auth/sq_auth_user/basic_user.rb +10 -0
- data/lib/sq_auth/sq_auth_user/rack_user.rb +11 -0
- data/lib/sq_auth/sq_auth_utils.rb +12 -0
- data/lib/sq_auth/version.rb +3 -0
- data/lib/sq_auth.rb +68 -0
- data/spec/lib/sq_auth/sq_auth_client_spec.rb +30 -0
- data/spec/lib/sq_auth/sq_auth_request_spec.rb +40 -0
- data/spec/lib/sq_auth/sq_auth_server_interface/basic_server_spec.rb +24 -0
- data/spec/lib/sq_auth/sq_auth_sessions_spec.rb +3 -0
- data/spec/lib/sq_auth/sq_auth_user/basic_user_spec.rb +5 -0
- data/spec/lib/sq_auth_spec.rb +5 -0
- data/spec/spec_helper.rb +1 -0
- data/sq_auth.gemspec +24 -0
- metadata +125 -0
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Rakefile
ADDED
data/examples/client.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'sq_auth'
|
3
|
+
|
4
|
+
enable :sessions
|
5
|
+
set :port, 7842
|
6
|
+
|
7
|
+
SqAuth.connect(host: "localhost", port: 3000) do |d|
|
8
|
+
d.project_name = "Project"
|
9
|
+
end
|
10
|
+
|
11
|
+
get ["admin"], "/something" do
|
12
|
+
<<-EOF
|
13
|
+
Logined to something with params #{params}
|
14
|
+
<br>
|
15
|
+
#{SqAuth.with_sq_auth("admin::super", "Project"){"You can't see it"}}
|
16
|
+
<br>
|
17
|
+
#{access_for("admin"){"You can see it"}}
|
18
|
+
EOF
|
19
|
+
end
|
20
|
+
|
21
|
+
get "/abc" do
|
22
|
+
params.to_s
|
23
|
+
end
|
data/examples/server.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'json'
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
set :port, 7843
|
6
|
+
|
7
|
+
get "/health" do
|
8
|
+
"OK"
|
9
|
+
end
|
10
|
+
|
11
|
+
post "/check_role" do
|
12
|
+
unless params[:role][/admin/]
|
13
|
+
{:role_exist => true}.to_json
|
14
|
+
else
|
15
|
+
{:role_exist => false}.to_json
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
get "/login" do
|
20
|
+
uri = URI::parse(params[:callback])
|
21
|
+
new_uri = URI::HTTP.build(host: uri.host, port: uri.port, path: "/save_session")
|
22
|
+
|
23
|
+
<<-EOF
|
24
|
+
<body>
|
25
|
+
<a href='#{params[:callback]}'>Back</a>
|
26
|
+
<form action="#{new_uri}" method="post">
|
27
|
+
<input type="text" name="sqauthsession" value="mydata" />
|
28
|
+
<input style="display:none" type="text" name="callback" value="#{params[:callback]}" />
|
29
|
+
<input type="submit" />
|
30
|
+
</form>
|
31
|
+
</body>
|
32
|
+
EOF
|
33
|
+
end
|
34
|
+
|
35
|
+
get "/push_session" do
|
36
|
+
push_session_to_client params[:client]
|
37
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module SqAuth
|
2
|
+
class SqAuthAccess
|
3
|
+
DEFAULT_ACCESS_PATH = "/access_partial"
|
4
|
+
DEFAULT_DRAW_PROC = Proc.new {|uri, callback, role, project, session| SqAuthUtils::default_draw_template(uri, callback, role, project, session)}
|
5
|
+
DEFAULT_DATA_PROC = Proc.new { "Forbidden" }
|
6
|
+
DEFAULT_OPTIONS = {project: "Project", https: true}
|
7
|
+
attr_accessor :login_path, :callback, :project_name, :gateway_ip
|
8
|
+
def initialize options={}
|
9
|
+
@options = options
|
10
|
+
@data_proc = DEFAULT_DATA_PROC
|
11
|
+
@draw_proc = DEFAULT_DRAW_PROC
|
12
|
+
@login_path = DEFAULT_ACCESS_PATH
|
13
|
+
@gateway_ip = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect options = {}
|
17
|
+
options = DEFAULT_OPTIONS.merge(options)
|
18
|
+
@project_name = options[:project]
|
19
|
+
@gateway_ip = options[:gateway_ip]
|
20
|
+
yield self if block_given?
|
21
|
+
SqAuthIntegration.alter_environment options
|
22
|
+
@session_provider = SqAuthClient.new options
|
23
|
+
end
|
24
|
+
|
25
|
+
def draw_when_not_logged_in &block
|
26
|
+
@draw_proc = block
|
27
|
+
end
|
28
|
+
|
29
|
+
def data_when_not_logged_in &block
|
30
|
+
@data_proc = Proc.new {|*args| block.call(*args)}
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_not_logged_in_proc type = nil
|
34
|
+
if type == true || type.nil?
|
35
|
+
@draw_proc
|
36
|
+
else
|
37
|
+
@data_proc
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_session_provider
|
42
|
+
raise "Authentication service not specified" unless @session_provider
|
43
|
+
# raise "Authentication service unavailable" unless @session_provider.available?
|
44
|
+
end
|
45
|
+
|
46
|
+
def api_filter(roles, project = @project_name, when_ok, when_no_role, options)
|
47
|
+
check_session_provider
|
48
|
+
not_logged_in_proc = get_not_logged_in_proc(options[:draw])
|
49
|
+
if sq_auth_filter(roles, project, options)
|
50
|
+
when_ok.call
|
51
|
+
else
|
52
|
+
when_no_role.(not_logged_in_proc.(login_to, callback, roles, project, @session_provider.session_for_current_user))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def sq_auth_filter(roles, project = @project_name, options = {})
|
57
|
+
@session_provider.session_for_current_user && @session_provider.role_exist_for_current_user?(roles, project)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def when_not_authenticated(roles, project, options = {})
|
62
|
+
not_logged_in_proc = get_not_logged_in_proc(options[:draw])
|
63
|
+
not_logged_in_proc.call(login_to, callback, roles, project, @session_provider.session_for_current_user)
|
64
|
+
end
|
65
|
+
|
66
|
+
def draw_when_not_authenticated(roles, project = @project_name)
|
67
|
+
when_not_authenticated(roles, project, {:draw => true})
|
68
|
+
end
|
69
|
+
|
70
|
+
def message_when_not_authenticated(roles = [], project = @project_name)
|
71
|
+
when_not_authenticated(roles, project, {:draw => false})
|
72
|
+
end
|
73
|
+
|
74
|
+
def with_sq_auth(roles, project = @project_name, options = {}, &block)
|
75
|
+
check_session_provider
|
76
|
+
binded_self = options[:binding].is_a?(Binding) ? eval("self", options[:binding]) : self
|
77
|
+
if sq_auth_filter(roles, project, options)
|
78
|
+
binded_self.instance_eval(&block) if block_given?
|
79
|
+
else
|
80
|
+
when_not_authenticated(roles, project, options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def save_session_for_current_user sqauthsession
|
85
|
+
@session_provider.create_session_for_current_user sqauthsession
|
86
|
+
end
|
87
|
+
|
88
|
+
def current_user_ip= ip
|
89
|
+
if @gateway_ip
|
90
|
+
@session_provider.user.user_ip = @gateway_ip
|
91
|
+
else
|
92
|
+
@session_provider.user.user_ip = ip
|
93
|
+
end
|
94
|
+
p @session_provider.user.user_ip
|
95
|
+
end
|
96
|
+
|
97
|
+
def login_to
|
98
|
+
uri = @session_provider.auth_server_uri
|
99
|
+
uri.path = "#@login_path"
|
100
|
+
uri.to_s
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module SqAuth
|
2
|
+
class SqAuthClient
|
3
|
+
|
4
|
+
def initialize options = {}
|
5
|
+
@https = !!options[:https]
|
6
|
+
@host = options[:host] || "localhost"
|
7
|
+
@port = (options[:port] || (@https ? 443 : 80)).to_i
|
8
|
+
@username = options[:username]
|
9
|
+
@password = options[:password]
|
10
|
+
@server = options[:server_type] || SqAuth::SqAuthServer::BasicServer
|
11
|
+
@user = options[:user_type] || SqAuth::SqAuthUser::BasicUser.new
|
12
|
+
@sessions = SqAuth::SqAuthSessions.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_session_for_current_user session
|
16
|
+
create_session current_user, session
|
17
|
+
end
|
18
|
+
|
19
|
+
def session_for_current_user
|
20
|
+
session_for current_user
|
21
|
+
end
|
22
|
+
|
23
|
+
def check_connection
|
24
|
+
send_request :check_connection
|
25
|
+
end
|
26
|
+
|
27
|
+
def available?
|
28
|
+
response = check_connection
|
29
|
+
response.is_a?(Hash) && response[:status] == "200"
|
30
|
+
end
|
31
|
+
|
32
|
+
def role_exist_for_current_user? role, project
|
33
|
+
role_exist? current_user, role, project
|
34
|
+
end
|
35
|
+
|
36
|
+
def user
|
37
|
+
@user
|
38
|
+
end
|
39
|
+
|
40
|
+
def current_user
|
41
|
+
@user.current_user
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_session user, session
|
45
|
+
@sessions[user] = session
|
46
|
+
end
|
47
|
+
|
48
|
+
def session_for user
|
49
|
+
p @sessions
|
50
|
+
@sessions[user]
|
51
|
+
end
|
52
|
+
|
53
|
+
def role_exist? user, roles, project
|
54
|
+
request_hash = {sqauthsession: session_for(user), roles: [*roles], auth_name: project, ip: user[:ip]}
|
55
|
+
response = send_request :check_role, request_hash
|
56
|
+
response.is_a?(Hash) && response[:data].is_a?(Hash) && (response[:data]["role_exist"] == true)
|
57
|
+
end
|
58
|
+
|
59
|
+
def send_request request_name, params = nil
|
60
|
+
@server.send(request_name, params, host_options)
|
61
|
+
end
|
62
|
+
|
63
|
+
def host_options
|
64
|
+
{host: @host, port: @port, username: @username, password: @password, https: @https}
|
65
|
+
end
|
66
|
+
|
67
|
+
def auth_server_uri
|
68
|
+
uri_builder = (@https ? URI::HTTPS : URI::HTTP)
|
69
|
+
uri_builder.build(host: @host, port: @port)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthHelpers
|
3
|
+
module DSL
|
4
|
+
def sq_auth_access &block
|
5
|
+
self.instance_eval &block
|
6
|
+
end
|
7
|
+
|
8
|
+
def access_actions *actions, &block
|
9
|
+
@sq_auth_actions_only = *actions
|
10
|
+
yield block if block_given?
|
11
|
+
@sq_auth_actions_only = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def access_action *action, &block
|
15
|
+
access_actions [*action], &block
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
def draw_for *roles, &block
|
21
|
+
access_for([*roles], &block)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
module SinatraDSL
|
27
|
+
def show_to *roles
|
28
|
+
create_filter [*roles]
|
29
|
+
end
|
30
|
+
def execute_for *roles
|
31
|
+
create_filter [*roles], {draw: false}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module RailsDSL
|
36
|
+
def access_actions_except *actions, &block
|
37
|
+
@sq_auth_actions_except = *actions
|
38
|
+
yield block if block_given?
|
39
|
+
@sq_auth_actions_except = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def access_action_except *action, &block
|
43
|
+
access_actions_except [*action], &block
|
44
|
+
end
|
45
|
+
|
46
|
+
def method_missing m, *args, &block
|
47
|
+
begin
|
48
|
+
super
|
49
|
+
rescue NoMethodError
|
50
|
+
if m[/^show_.+_to$/]
|
51
|
+
format = m.to_s.scan(/^show_(.+)_to$/).flatten.first
|
52
|
+
create_filter args, {:format_type => format}
|
53
|
+
else
|
54
|
+
raise NoMethodError
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthHelpers
|
3
|
+
module ActionController
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
include SqAuth::SqAuthHelpers::DSL
|
10
|
+
include SqAuth::SqAuthHelpers::RailsDSL
|
11
|
+
def create_filter roles, options = {}
|
12
|
+
filter_options = {}
|
13
|
+
filter_options[:only] = @sq_auth_actions_only
|
14
|
+
filter_options[:except] = @sq_auth_actions_except
|
15
|
+
before_filter(filter_options) do |controller|
|
16
|
+
format_type = options[:format_type]
|
17
|
+
format_condition = (format_type == "all") || (format_type.nil?) || (controller.request.format.send("#{format_type}?".to_sym))
|
18
|
+
if format_condition
|
19
|
+
error_proc = nil
|
20
|
+
api_options = {}
|
21
|
+
if format_type == "json"
|
22
|
+
error_proc = Proc.new do |message|
|
23
|
+
render json: message
|
24
|
+
end
|
25
|
+
api_options[:draw] = false
|
26
|
+
else
|
27
|
+
error_proc = Proc.new do |message|
|
28
|
+
render text: message
|
29
|
+
end
|
30
|
+
api_options[:draw] = true
|
31
|
+
end
|
32
|
+
SqAuth.api_filter(roles, Proc.new {}, error_proc, api_options)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthHelpers
|
3
|
+
module Sinatra
|
4
|
+
include SqAuth::SqAuthHelpers::SinatraDSL
|
5
|
+
include SqAuth::SqAuthHelpers::DSL
|
6
|
+
|
7
|
+
def create_filter roles, options = {}
|
8
|
+
action = nil
|
9
|
+
action = [*@sq_auth_actions_only].flatten.first if @sq_auth_actions_only
|
10
|
+
|
11
|
+
if !roles.empty?
|
12
|
+
ok_proc = Proc.new {}
|
13
|
+
error_proc = Proc.new do |message|
|
14
|
+
throw(:halt, [401, message])
|
15
|
+
end
|
16
|
+
before(action) do
|
17
|
+
SqAuth.api_filter(roles, ok_proc, error_proc, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthIntegration
|
3
|
+
module SqAuthActionController
|
4
|
+
def self.check_environment
|
5
|
+
defined?(ActionController::Base)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.alter_environment options={}
|
9
|
+
ActionController::Base.instance_eval do
|
10
|
+
include SqAuth::SqAuthHelpers::ActionController
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthIntegration
|
3
|
+
def self.alter_environment options = {}
|
4
|
+
@already_altered ||= []
|
5
|
+
alter_modules = SqAuth::SqAuthIntegration.constants.map do |const|
|
6
|
+
alter_module = nil
|
7
|
+
check_module = SqAuth::SqAuthIntegration.const_get(const)
|
8
|
+
if check_module.kind_of?(Module) && check_module.respond_to?(:alter_environment) && check_module.respond_to?(:check_environment)
|
9
|
+
alter_module = check_module
|
10
|
+
end
|
11
|
+
alter_module
|
12
|
+
end.compact
|
13
|
+
alter_modules.each do |m|
|
14
|
+
unless @already_altered.include? m
|
15
|
+
if m.check_environment
|
16
|
+
@already_altered << m
|
17
|
+
m.alter_environment options
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthIntegration
|
3
|
+
module SqAuthRack
|
4
|
+
def self.check_environment
|
5
|
+
defined?(Rack)
|
6
|
+
end
|
7
|
+
def self.alter_environment options={}
|
8
|
+
if defined?(Rails)
|
9
|
+
Rails.application.class.instance_eval do
|
10
|
+
config.middleware.use Rack::Session::Cookie, :expire_after => 2592000
|
11
|
+
config.middleware.use SqAuth::SqAuthIntegration::SqAuthRack::Middleware
|
12
|
+
end
|
13
|
+
else
|
14
|
+
use Rack::Session::Cookie, :expire_after => 2592000
|
15
|
+
use SqAuth::SqAuthIntegration::SqAuthRack::Middleware
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Middleware
|
20
|
+
attr_accessor :app, :env
|
21
|
+
def call(env)
|
22
|
+
req = Rack::Request.new(env)
|
23
|
+
SqAuth.access.callback = callback_uri(env)
|
24
|
+
SqAuth.access.current_user_ip = env["HTTP_X_FORWARDED_FOR"] || env["REMOTE_ADDR"]
|
25
|
+
SqAuth.access.save_session_for_current_user (env["rack.session"]||{})[:sqauthsession]
|
26
|
+
form_hash = req.params||{}
|
27
|
+
if auth_request?(env, form_hash)
|
28
|
+
redirect_to_callback(env, form_hash)
|
29
|
+
else
|
30
|
+
pass_through env
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def auth_request? env, form_hash
|
35
|
+
env["REQUEST_METHOD"] == "POST" && form_hash.keys.include?("sqauthsession") && form_hash.keys.include?("callback")
|
36
|
+
end
|
37
|
+
|
38
|
+
def redirect_to_callback env, form_hash
|
39
|
+
env["rack.session"][:sqauthsession] = form_hash["sqauthsession"] if env["rack.session"]
|
40
|
+
SqAuth.access.save_session_for_current_user form_hash["sqauthsession"]
|
41
|
+
|
42
|
+
[302, {'Location' => form_hash["callback"]}, ['Authenticated']]
|
43
|
+
end
|
44
|
+
|
45
|
+
def callback_uri env
|
46
|
+
if URI.parse(env["REQUEST_URI"]).host
|
47
|
+
env["REQUEST_URI"]
|
48
|
+
else
|
49
|
+
uri_type = URI.const_get(env["HTTP_X_URL_SCHEME"].upcase) rescue nil
|
50
|
+
uri_type ||= URI.const_get(env["rack.url_scheme"].upcase) rescue nil
|
51
|
+
uri_type ||= URI::HTTP
|
52
|
+
if env["HTTP_HOST"].is_a? String
|
53
|
+
host, port = env["HTTP_HOST"].split(":")
|
54
|
+
end
|
55
|
+
host ||= env["SERVER_NAME"]
|
56
|
+
port ||= env["SERVER_PORT"]
|
57
|
+
path = env["REQUEST_PATH"].to_s
|
58
|
+
if path.empty?
|
59
|
+
path = URI::parse(env["PATH_INFO"]).path rescue ""
|
60
|
+
end
|
61
|
+
if path.empty?
|
62
|
+
path = URI::parse(env["REQUEST_URI"]).path
|
63
|
+
end
|
64
|
+
query = env["QUERY_STRING"]
|
65
|
+
if port
|
66
|
+
uri = uri_type.build(host: host, port: port.to_i, path: path, query: query)
|
67
|
+
else
|
68
|
+
uri = uri_type.build(host: host, path: path, query: query)
|
69
|
+
end
|
70
|
+
uri.to_s
|
71
|
+
end
|
72
|
+
rescue Exception => ex
|
73
|
+
p ex.message
|
74
|
+
return ""
|
75
|
+
end
|
76
|
+
|
77
|
+
def pass_through env
|
78
|
+
status, headers, response = app.call(env)
|
79
|
+
[status, headers, response]
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize(app)
|
83
|
+
@app = app
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthIntegration
|
3
|
+
module SqAuthRackProtection
|
4
|
+
|
5
|
+
def self.check_environment
|
6
|
+
defined?(Rack::Protection::RemoteToken)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.alter_environment options={}
|
10
|
+
# Sorry, Konstantin
|
11
|
+
except_host = options[:host]
|
12
|
+
Rack::Protection::RemoteToken.class_exec(except_host) do |except|
|
13
|
+
const_set("HOST", except)
|
14
|
+
alias :old_accepts? :accepts?
|
15
|
+
def accepts?(env)
|
16
|
+
form_hash = env["rack.request.form_hash"]||{}
|
17
|
+
if referrer(env) == HOST && env["REQUEST_METHOD"] == "POST" && form_hash.keys.include?("sqauthsession")
|
18
|
+
true
|
19
|
+
else
|
20
|
+
old_accepts?(env)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthIntegration
|
3
|
+
module SqAuthSinatra
|
4
|
+
|
5
|
+
def self.check_environment
|
6
|
+
defined?(Sinatra)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.alter_environment options={}
|
10
|
+
Sinatra.register SqAuth::SqAuthHelpers::Sinatra
|
11
|
+
Sinatra::Base.instance_eval do
|
12
|
+
alias :old_get :get
|
13
|
+
def get(*args, &block)
|
14
|
+
roles = []
|
15
|
+
if args[0].is_a?(Array)
|
16
|
+
roles << args[0]
|
17
|
+
args.shift
|
18
|
+
end
|
19
|
+
roles.flatten!
|
20
|
+
if !roles.empty?
|
21
|
+
ok_proc = Proc.new {}
|
22
|
+
error_proc = Proc.new do |message|
|
23
|
+
throw(:halt, [401, message])
|
24
|
+
end
|
25
|
+
before(*args) do
|
26
|
+
SqAuth.api_filter(roles, ok_proc, error_proc)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
old_get(*args, &block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module SqAuth
|
2
|
+
class SqAuthRequest
|
3
|
+
|
4
|
+
def self.hash_to_query hash
|
5
|
+
query = ""
|
6
|
+
encode_chars = Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
7
|
+
if hash.is_a? Hash
|
8
|
+
query = hash.map do |param_name, param_value|
|
9
|
+
if param_value.is_a? Array
|
10
|
+
param_value.map do |v|
|
11
|
+
"#{param_name}[]=#{URI::encode(v.to_s, encode_chars)}"
|
12
|
+
end.join("&")
|
13
|
+
else
|
14
|
+
"#{param_name}=#{URI::encode(param_value.to_s, encode_chars)}"
|
15
|
+
end
|
16
|
+
end.join("&")
|
17
|
+
end
|
18
|
+
query
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.parse_response response = nil
|
22
|
+
data = nil
|
23
|
+
if response.is_a? Net::HTTPResponse
|
24
|
+
data = {}
|
25
|
+
data[:status] = response.code
|
26
|
+
data[:message] = response.message
|
27
|
+
if response.is_a? Net::HTTPOK
|
28
|
+
data[:data] = begin
|
29
|
+
JSON::load(response.body)
|
30
|
+
rescue JSON::ParserError
|
31
|
+
response.body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
data
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize options
|
39
|
+
@host = options[:host] || raise("Host not specified")
|
40
|
+
@port = options[:port] || 80
|
41
|
+
@username = options[:username]
|
42
|
+
@password = options[:password]
|
43
|
+
path = options[:path]
|
44
|
+
absolute_path = "/"
|
45
|
+
if path.is_a? Symbol
|
46
|
+
absolute_path << path.to_s
|
47
|
+
elsif path.is_a? String
|
48
|
+
absolute_path << path
|
49
|
+
end
|
50
|
+
@path = absolute_path
|
51
|
+
method = options[:method] || :get
|
52
|
+
@https = !!options[:https]
|
53
|
+
@method = ::Net::HTTP.const_get(method.to_s.capitalize)
|
54
|
+
@uri_builder = @https ? URI::HTTPS : URI::HTTP
|
55
|
+
end
|
56
|
+
|
57
|
+
def setup_query query_hash
|
58
|
+
@query = SqAuthRequest.hash_to_query(query_hash)
|
59
|
+
@uri = @uri_builder.build(host: @host, port: @port, path: @path, query: (@method == Net::HTTP::Get)? @query: nil)
|
60
|
+
@http = Net::HTTP.new(@uri.host, @uri.port)
|
61
|
+
@http.use_ssl = @https
|
62
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @https
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def request query = {}
|
67
|
+
setup_query(query)
|
68
|
+
response = get_response
|
69
|
+
SqAuthRequest.parse_response response
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_response
|
73
|
+
request = @method.new(@uri.request_uri)
|
74
|
+
if @username && @password
|
75
|
+
request.basic_auth @username, @password
|
76
|
+
end
|
77
|
+
send_data(request)
|
78
|
+
end
|
79
|
+
|
80
|
+
def send_data request
|
81
|
+
if @method == Net::HTTP::Post
|
82
|
+
request.body = @query
|
83
|
+
request.content_length = request.body.bytesize
|
84
|
+
end
|
85
|
+
@http.request(request) rescue nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthServer
|
3
|
+
class BasicServer
|
4
|
+
SERVER_INTERFACE = {
|
5
|
+
check_connection: {path: "health", method: :get},
|
6
|
+
check_role: {path: "check_role", method: :post}
|
7
|
+
}
|
8
|
+
|
9
|
+
def self.init_request specification, host_options = {}
|
10
|
+
options = {}
|
11
|
+
options[:host] = host_options[:host]
|
12
|
+
options[:port] = host_options[:port]
|
13
|
+
options[:username] = host_options[:username]
|
14
|
+
options[:password] = host_options[:password]
|
15
|
+
options[:https] = host_options[:https]
|
16
|
+
options[:path] = specification[:path]
|
17
|
+
options[:method] = specification[:method]
|
18
|
+
SqAuthRequest.new options
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.sq_auth_host host_options
|
22
|
+
{host: host_options[:host], port: host_options[:port]}
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.use_interface interface, query, host_options = {}
|
26
|
+
interface[:requests] ||= {}
|
27
|
+
interface[:requests][sq_auth_host(host_options)] ||= init_request(interface, host_options)
|
28
|
+
interface[:requests][sq_auth_host(host_options)].request query
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.method_missing m, *args, &block
|
32
|
+
if SERVER_INTERFACE[m]
|
33
|
+
use_interface(SERVER_INTERFACE[m], *args)
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module SqAuth
|
2
|
+
module SqAuthUtils
|
3
|
+
def self.default_draw_template uri, callback, role, project, session
|
4
|
+
<<-EOF
|
5
|
+
<div class="sq_auth_not_logged_in">
|
6
|
+
<iframe src='#{uri}?#{SqAuth::SqAuthRequest.hash_to_query({callback: callback, roles: [*role], auth_name: project, sqauthsession: session})}'>
|
7
|
+
</iframe>
|
8
|
+
</div>
|
9
|
+
EOF
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/sq_auth.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# external dependencies
|
2
|
+
require 'uri'
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'openssl'
|
6
|
+
require 'json'
|
7
|
+
require 'digest'
|
8
|
+
|
9
|
+
# internal dependencies
|
10
|
+
require "sq_auth/version"
|
11
|
+
require "sq_auth/sq_auth_access"
|
12
|
+
require "sq_auth/sq_auth_client"
|
13
|
+
require "sq_auth/sq_auth_request"
|
14
|
+
require "sq_auth/sq_auth_sessions"
|
15
|
+
require "sq_auth/sq_auth_utils"
|
16
|
+
require "sq_auth/sq_auth_server_interface/basic_server"
|
17
|
+
require "sq_auth/sq_auth_user/basic_user"
|
18
|
+
require "sq_auth/sq_auth_user/rack_user"
|
19
|
+
require "sq_auth/sq_auth_integration/sq_auth_integration"
|
20
|
+
require "sq_auth/sq_auth_integration/sq_auth_rack"
|
21
|
+
require "sq_auth/sq_auth_integration/sq_auth_rack_protection"
|
22
|
+
require "sq_auth/sq_auth_integration/sq_auth_sinatra"
|
23
|
+
require "sq_auth/sq_auth_integration/sq_auth_action_controller"
|
24
|
+
require "sq_auth/sq_auth_helpers/sq_auth_helpers_dsl"
|
25
|
+
require "sq_auth/sq_auth_helpers/sq_auth_helpers_rails"
|
26
|
+
require "sq_auth/sq_auth_helpers/sq_auth_helpers_sinatra"
|
27
|
+
|
28
|
+
module SqAuth
|
29
|
+
@session_access = SqAuth::SqAuthAccess.new
|
30
|
+
def self.connect(*args, &block)
|
31
|
+
@session_access.connect(*args, &block)
|
32
|
+
end
|
33
|
+
def self.access
|
34
|
+
@session_access
|
35
|
+
end
|
36
|
+
def self.with_sq_auth(*args, &block)
|
37
|
+
@session_access.with_sq_auth(*args, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.api_filter(roles, ok_proc, error_proc, options = {})
|
41
|
+
@session_access.api_filter(roles, SqAuth.access.project_name, ok_proc, error_proc, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.included(base)
|
45
|
+
base.send :include, InstanceMethods
|
46
|
+
end # self.included
|
47
|
+
|
48
|
+
module InstanceMethods
|
49
|
+
def access_for(*roles, &block)
|
50
|
+
SqAuth.with_sq_auth([*roles], SqAuth.access.project_name, {:binding => binding}, &block)
|
51
|
+
end
|
52
|
+
alias :draw_for :access_for
|
53
|
+
|
54
|
+
def accessed_by?(*roles)
|
55
|
+
SqAuth.access.sq_auth_filter([*roles])
|
56
|
+
end
|
57
|
+
|
58
|
+
def not_accessible_message
|
59
|
+
SqAuth.access.message_when_not_authenticated
|
60
|
+
end
|
61
|
+
|
62
|
+
def not_accessible_link(*roles)
|
63
|
+
SqAuth.access.draw_when_not_authenticated(roles)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
include SqAuth
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe SqAuth::SqAuthClient do
|
4
|
+
let(:client) {SqAuth::SqAuthClient.new}
|
5
|
+
let(:user1) { {name: "user1", ip: "234.24.23.1" } }
|
6
|
+
let(:user2) { {name: "user2", ip: "234.24.23.2" } }
|
7
|
+
let(:user3) { {name: "user3", ip: "234.24.23.3" } }
|
8
|
+
|
9
|
+
it "saves user session" do
|
10
|
+
SqAuth::SqAuthUser::BasicUser.stub(:current_user).and_return(user1)
|
11
|
+
client.create_session_for_current_user(Digest::MD5.digest(user1.to_s)).should_not == nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it "checks for existance of user session" do
|
15
|
+
client.session_for(user2).should == nil
|
16
|
+
SqAuth::SqAuthUser::BasicUser.stub(:current_user).and_return(user3)
|
17
|
+
user3_session = client.create_session_for_current_user(Digest::MD5.digest(user3.to_s))
|
18
|
+
client.session_for_current_user.should == user3_session
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sends check request to auth server" do
|
22
|
+
client.stub(:send_request).with(:check_connection).and_return("ok")
|
23
|
+
client.check_connection.should_not == nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "checks for role for sessioned user" do
|
27
|
+
client.stub(:send_request).with(:check_role, {sqauthsession: client.session_for_current_user, roles: ["role"], auth_name: "project", ip: "127.0.0.1"}).and_return("ok")
|
28
|
+
client.role_exist_for_current_user?("role", "project").should_not == nil
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe SqAuth::SqAuthRequest do
|
4
|
+
it 'convert hashes to http query strings' do
|
5
|
+
query_hash1 = {a: 1, b: "Hello", c: [123, "A B C", "+++"]}
|
6
|
+
query_string1 = "a=1&b=Hello&c[]=123&c[]=A%20B%20C&c[]=%2B%2B%2B"
|
7
|
+
SqAuth::SqAuthRequest.hash_to_query(query_hash1).should == query_string1
|
8
|
+
SqAuth::SqAuthRequest.hash_to_query({}).should == ""
|
9
|
+
SqAuth::SqAuthRequest.hash_to_query(nil).should == ""
|
10
|
+
SqAuth::SqAuthRequest.hash_to_query([1,2,3,4]).should == ""
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'parse http responses' do
|
14
|
+
example_ok = Net::HTTPOK.new(1.1, '200', 'Ok')
|
15
|
+
example_ok.stub(:body).and_return("{\"a\": 1}")
|
16
|
+
SqAuth::SqAuthRequest.parse_response(example_ok).should == {status: "200", message: "Ok", data: {"a" => 1}}
|
17
|
+
|
18
|
+
example_error = Net::HTTPNotFound.new(1.1, '404', 'Page not found')
|
19
|
+
SqAuth::SqAuthRequest.parse_response(example_error).should == {status: "404", message: "Page not found"}
|
20
|
+
|
21
|
+
example_ok_with_not_json_body = Net::HTTPOK.new(1.1, '200', 'Ok')
|
22
|
+
example_ok.stub(:body).and_return("<title>Test</title><body>Body of the page</body>")
|
23
|
+
SqAuth::SqAuthRequest.parse_response(example_ok).should == {status: "200", message: "Ok", data: "<title>Test</title><body>Body of the page</body>"}
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should not fail if host unreachable' do
|
27
|
+
request = SqAuth::SqAuthRequest.new(host: "fake", path: "health", method: "get")
|
28
|
+
lambda {request.request({a: 1, b: 2})}.should_not raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'send request to sq_auth server and parses response' do
|
32
|
+
request = SqAuth::SqAuthRequest.new(host: "localhost", path: "", method: "get")
|
33
|
+
example_ok = Net::HTTPOK.new(1.1, '200', 'Ok')
|
34
|
+
example_ok.stub(:body).and_return("{\"a\": 1}")
|
35
|
+
request.stub(:send_data).with(kind_of(Net::HTTP::Get)).and_return(example_ok)
|
36
|
+
request.request({}).should == {status: "200", message: "Ok", data: {"a" => 1}}
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe SqAuth::SqAuthServer::BasicServer do
|
4
|
+
it 'should create request to custom sq_auth server once per server and send data to server by created request' do
|
5
|
+
host_options = {host: "localhost", port: 80}
|
6
|
+
interface = SqAuth::SqAuthServer::BasicServer::SERVER_INTERFACE[:check_connection]
|
7
|
+
mock_req = SqAuth::SqAuthRequest.new(host_options.merge({method: :get, path: "health"}))
|
8
|
+
|
9
|
+
# should create 2 requests: localhost/check_connection and localhost/check_role
|
10
|
+
SqAuth::SqAuthRequest.should_receive(:new).exactly(2).and_return(mock_req)
|
11
|
+
to_return = {status: "200", message: "Ok", data: {"a" => 1}}
|
12
|
+
|
13
|
+
# should send data 3 times by 2 request requests: localhost/check_connection, localhost/check_connection, and localhost/check_role
|
14
|
+
mock_req.should_receive(:request).exactly(3).and_return(to_return)
|
15
|
+
|
16
|
+
SqAuth::SqAuthServer::BasicServer.check_connection({}, host_options)[:data].should == {"a" => 1}
|
17
|
+
SqAuth::SqAuthServer::BasicServer.check_connection({}, host_options)[:data].should == {"a" => 1}
|
18
|
+
SqAuth::SqAuthServer::BasicServer.check_role({}, host_options)[:data].should == {"a" => 1}
|
19
|
+
|
20
|
+
SqAuth::SqAuthServer::BasicServer::SERVER_INTERFACE[:check_connection][:requests][host_options].should be_a_kind_of SqAuth::SqAuthRequest
|
21
|
+
SqAuth::SqAuthServer::BasicServer::SERVER_INTERFACE[:check_role][:requests][host_options].should be_a_kind_of SqAuth::SqAuthRequest
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'sq_auth'
|
data/sq_auth.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "sq_auth/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "sq_auth"
|
7
|
+
s.version = SqAuth::VERSION
|
8
|
+
s.authors = ["Leonid Krinitsyn"]
|
9
|
+
s.email = ["leonidkrn@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{SQ sevices authentication gem}
|
12
|
+
s.description = %q{SQ sevices authentication gem}
|
13
|
+
|
14
|
+
s.rubyforge_project = "sq_auth"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency 'rake'
|
22
|
+
s.add_development_dependency 'rspec'
|
23
|
+
s.add_development_dependency 'sinatra'
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sq_auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.18
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Leonid Krinitsyn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-05 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sinatra
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: SQ sevices authentication gem
|
63
|
+
email:
|
64
|
+
- leonidkrn@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- Gemfile
|
72
|
+
- Rakefile
|
73
|
+
- examples/client.rb
|
74
|
+
- examples/server.rb
|
75
|
+
- lib/sq_auth.rb
|
76
|
+
- lib/sq_auth/sq_auth_access.rb
|
77
|
+
- lib/sq_auth/sq_auth_client.rb
|
78
|
+
- lib/sq_auth/sq_auth_helpers/sq_auth_helpers_dsl.rb
|
79
|
+
- lib/sq_auth/sq_auth_helpers/sq_auth_helpers_rails.rb
|
80
|
+
- lib/sq_auth/sq_auth_helpers/sq_auth_helpers_sinatra.rb
|
81
|
+
- lib/sq_auth/sq_auth_integration/sq_auth_action_controller.rb
|
82
|
+
- lib/sq_auth/sq_auth_integration/sq_auth_integration.rb
|
83
|
+
- lib/sq_auth/sq_auth_integration/sq_auth_rack.rb
|
84
|
+
- lib/sq_auth/sq_auth_integration/sq_auth_rack_protection.rb
|
85
|
+
- lib/sq_auth/sq_auth_integration/sq_auth_sinatra.rb
|
86
|
+
- lib/sq_auth/sq_auth_request.rb
|
87
|
+
- lib/sq_auth/sq_auth_server_interface/basic_server.rb
|
88
|
+
- lib/sq_auth/sq_auth_sessions.rb
|
89
|
+
- lib/sq_auth/sq_auth_user/basic_user.rb
|
90
|
+
- lib/sq_auth/sq_auth_user/rack_user.rb
|
91
|
+
- lib/sq_auth/sq_auth_utils.rb
|
92
|
+
- lib/sq_auth/version.rb
|
93
|
+
- spec/lib/sq_auth/sq_auth_client_spec.rb
|
94
|
+
- spec/lib/sq_auth/sq_auth_request_spec.rb
|
95
|
+
- spec/lib/sq_auth/sq_auth_server_interface/basic_server_spec.rb
|
96
|
+
- spec/lib/sq_auth/sq_auth_sessions_spec.rb
|
97
|
+
- spec/lib/sq_auth/sq_auth_user/basic_user_spec.rb
|
98
|
+
- spec/lib/sq_auth_spec.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- sq_auth.gemspec
|
101
|
+
homepage: ''
|
102
|
+
licenses: []
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project: sq_auth
|
121
|
+
rubygems_version: 1.8.18
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: SQ sevices authentication gem
|
125
|
+
test_files: []
|