Commit f62507b
Changed files (1)
bin
bin/idp
@@ -28,8 +28,12 @@ $port = ENV.fetch("PORT", 8282).to_i
$host = ENV.fetch("HOST", "localhost:#{$port}")
module HTTPHelpers
- def logged_in?(request)
- request.session[:user_id]
+ def current_user?(request)
+ current_user(request)
+ end
+
+ def current_user(request)
+ ::Authn::User.find(request.session[:user_id])
end
def default_headers
@@ -47,7 +51,7 @@ module HTTPHelpers
end
def http_redirect_to(location)
- [302, { 'Location' => location }, []]
+ [302, { 'Location' => "http://idp.example.com:8080#{location}" }, []]
end
end
@@ -67,6 +71,12 @@ module Authn
end
end
+ def find(id)
+ all.find do |user|
+ user[:id] == id
+ end
+ end
+
def find_by_username(username)
all.find do |user|
user[:username] == username
@@ -136,7 +146,8 @@ module Authn
when '/sessions'
if (user = User.find_by_credentials(request.params))
request.session[:user_id] = user[:id]
- return http_redirect_to('/')
+ path = request.params["redirect_back"] ? request.params["redirect_back"] : "/"
+ return http_redirect_to(path)
else
return http_redirect_to("/sessions/new")
end
@@ -159,6 +170,7 @@ module Authn
<body>
<form id="login-form" action="/sessions" method="post">
<input type="input" placeholder="Username" id="username" name="username" value="" />
+ <input type="hidden" name="redirect_back" value="<%= request.params["redirect_back"] %>" />
<input type="password" placeholder="Password" id="password" name="password" value="" />
<input type="submit" id="login-button" value="Login" />
</form>
@@ -194,26 +206,33 @@ module Authn
end
def call(env)
- path = env['PATH_INFO']
- case env['REQUEST_METHOD']
- when 'GET'
- case path
- when "/metadata.xml"
+ request = Rack::Request.new(env)
+ case request.request_method
+ when Rack::GET
+ case request.path
+ when "/saml/continue"
+ if current_user?(request)
+ saml_params = request.session[:saml_params]
+ return saml_post_back(request, current_user(request), saml_params)
+ else
+ return http_redirect_to("/sessions/new?redirect_back=/saml/continue")
+ end
+ when "/saml/metadata.xml"
return http_ok(
{ 'Content-Type' => "application/samlmetadata+xml" },
saml_metadata.to_xml(pretty: true)
)
end
- when 'POST'
- case path
- when "/new"
- return login_page(Rack::Request.new(env))
- when "/login"
- request = Rack::Request.new(env)
- if (user = User.find_by_credentials(request.params))
- return saml_post_back(request, user)
+ when Rack::POST
+ case request.path
+ when "/saml/new"
+ saml_params = saml_params_from(request)
+
+ if current_user?(request)
+ return saml_post_back(request, current_user(request), saml_params)
else
- return login_page(request)
+ request.session[:saml_params] = saml_params
+ return http_redirect_to("/sessions/new?redirect_back=/saml/continue")
end
end
end
@@ -225,45 +244,14 @@ module Authn
attr_reader :saml_metadata
- def login_page(request)
- saml_params = saml_params_from(request)
+ def saml_post_back(request, user, saml_params)
saml_request = binding_for(request).deserialize(saml_params)
- raise saml_request.errors unless saml_request.valid?
-
- template = <<~ERB
- <!DOCTYPE html>
- <html>
- <head><title></title></head>
- <body>
- <h2>Recieved SAML Request</h2>
- <textarea readonly="readonly" disabled="disabled" cols=225 rows=6><%=- saml_request.to_xml(pretty: true) -%></textarea>
-
- <form id="login-form" action="/saml/login" method="post">
- <input type="input" placeholder="Username" id="username" name="username" value="" />
- <input type="password" placeholder="Password" id="password" name="password" value="" />
- <%- saml_params.each do |(key, value)| -%>
- <input type="hidden" name="<%= key %>" value="<%= value %>" />
- <%- end -%>
- <input type="submit" id="login-button" value="Login" />
- </form>
- </body>
- </html>
- ERB
- erb = ERB.new(template, trim_mode: '-')
- html = erb.result(binding)
- [200, { 'Content-Type' => "text/html" }, [html]]
- end
-
- def saml_post_back(request, user)
- params = saml_params_from(request)
- saml_request = binding_for(request).deserialize(params)
- request.session[:user_id] = user[:id]
@builder = nil
url, saml_params = saml_request.response_for(
user,
binding: :http_post,
- relay_state: params[:RelayState]
+ relay_state: saml_params[:RelayState]
) { |builder| @builder = builder }
template = <<~ERB
<!DOCTYPE html>
@@ -303,12 +291,7 @@ module Authn
end
def binding_for(request)
- location = "#{$scheme}://#{$host}/saml/new"
- if request.post?
- Saml::Kit::Bindings::HttpPost.new(location: location)
- else
- Saml::Kit::Bindings::HttpRedirect.new(location: location)
- end
+ Saml::Kit::Bindings::HttpPost.new(location: "#{$scheme}://#{$host}/saml/new")
end
end
end
@@ -395,7 +378,7 @@ module Authz
when Rack::GET
case request.path_info
when "/authorize" # RFC-6749
- if logged_in?(request)
+ if current_user?(request)
return get_authorize(request)
else
http_redirect_to("/saml/")
@@ -481,7 +464,7 @@ class IdentityProvider
when Rack::GET
case request.path
when '/'
- if logged_in?(request)
+ if current_user?(request)
return get_dashboard(request)
else
return http_redirect_to("/sessions/new")
@@ -507,8 +490,7 @@ class IdentityProvider
<html>
<head><title></title></head>
<body>
- <h1>Dashboard</h1>
- <pre><%= request.session[:access_token] %></pre>
+ <h1> Hello, <%= current_user(request)[:username] %></h1>
<form action="/sessions/delete" method="post">
<input type="submit" value="logout" />