Commit d9739b9

mo khan <mo@mokhan.ca>
2025-03-21 00:13:55
feat: use warden to manage authenticated session
1 parent 319986f
Changed files (1)
bin
bin/idp
@@ -16,6 +16,7 @@ gemfile do
   gem "rackup", "~> 2.0"
   gem "saml-kit", "~> 1.0"
   gem "twirp", "~> 1.0"
+  gem "warden", "~> 1.0"
   gem "webrick", "~> 1.0"
 end
 
@@ -28,13 +29,38 @@ $scheme = ENV.fetch("SCHEME", "http")
 $port = ENV.fetch("PORT", 8282).to_i
 $host = ENV.fetch("HOST", "localhost:#{$port}")
 
+DeclarativePolicy.configure do
+  name_transformation do |name|
+    "::Authz::#{name}Policy"
+  end
+end
+
+Warden::Manager.serialize_into_session do |user|
+  user.id
+end
+
+Warden::Manager.serialize_from_session do |id|
+  ::Authn::User.find(id)
+end
+
+Warden::Strategies.add(:password) do
+  def valid?
+    params['username'] && params['password']
+  end
+
+  def authenticate!
+    user = ::Authn::User.login(params.transform_keys(&:to_sym))
+    user.nil? ? fail!("Could not log in") : success!(user)
+  end
+end
+
 module HTTPHelpers
   def current_user?(request)
-    current_user(request)
+    request.env['warden'].authenticated?
   end
 
   def current_user(request)
-    ::Authn::User.find(request.session[:user_id])
+    request.env['warden'].user
   end
 
   def default_headers
@@ -52,7 +78,7 @@ module HTTPHelpers
   end
 
   def http_redirect_to(location)
-    [302, { 'Location' => "http://idp.example.com:8080#{location}" }, []]
+    [302, { 'Location' => "#{$scheme}://#{$host}#{location}" }, []]
   end
 end
 
@@ -151,21 +177,19 @@ module Authn
       when Rack::GET
         case request.path
         when '/sessions/new'
-          request.session.delete(:user_id)
           return get_login(request)
         end
       when Rack::POST
         case request.path
         when '/sessions'
-          if (user = User.login(request.params.transform_keys(&:to_sym)))
-            request.session[:user_id] = user[:id]
+          if (user = env['warden'].authenticate(:password))
             path = request.params["redirect_back"] ? request.params["redirect_back"] : "/"
             return http_redirect_to(path)
           else
             return http_redirect_to("/sessions/new")
           end
         when '/sessions/delete'
-          request.session.delete(:user_id)
+          request.env['warden'].logout
           return http_redirect_to('/')
         end
       end
@@ -317,12 +341,6 @@ class Organization
   end
 end
 
-DeclarativePolicy.configure do
-  name_transformation do |name|
-    "::Authz::#{name}Policy"
-  end
-end
-
 module Authz
   class OrganizationPolicy < DeclarativePolicy::Base
     condition(:owner) { true }
@@ -747,6 +765,10 @@ if __FILE__ == $0
     use Rack::CommonLogger
     use Rack::Reloader
     use Rack::Session::Cookie, { domain: $host.split(":", 2)[0], path: "/", secret: SecureRandom.hex(64) }
+    use ::Warden::Manager do |config|
+      config.default_scope = :user
+      config.default_strategies :password
+    end
 
     map "/twirp" do
       # https://github.com/arthurnn/twirp-ruby/wiki/Service-Handlers