Skip to content

Commit

Permalink
add session authn strategy to policies
Browse files Browse the repository at this point in the history
  • Loading branch information
ezekg committed Feb 26, 2025
1 parent 23232ff commit 91d6845
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 20 deletions.
10 changes: 6 additions & 4 deletions app/controllers/concerns/authentication.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ def query_token_authenticator(query_token)

def http_cookie_authenticator(cookie_jar)
session = current_account.sessions.for_environment(current_environment, strict: current_environment.nil?)
.find_by(id: cookie_jar[:session_id])
.preload(:token, :bearer)
.find_by(
id: cookie_jar[:session_id],
)

@current_http_scheme = :session
@current_http_token = nil
Expand All @@ -125,11 +128,10 @@ def http_cookie_authenticator(cookie_jar)
raise Keygen::Error::ForbiddenError.new(code: 'USER_BANNED', detail: 'User is banned') if
session.bearer.respond_to?(:banned?) && session.bearer.banned?

# treat session auth the same as token auth for licenses
case
when session.bearer.has_role?(:license)
raise Keygen::Error::ForbiddenError.new(code: 'SESSION_NOT_ALLOWED', detail: 'Session token authentication is not allowed by policy') unless
session.bearer.supports_token_auth?
raise Keygen::Error::ForbiddenError.new(code: 'SESSION_NOT_ALLOWED', detail: 'Session authentication is not allowed by policy') unless
session.bearer.supports_session_auth?
end

if session.last_used_at.nil? || session.last_used_at.before?(1.hour.ago)
Expand Down
1 change: 1 addition & 0 deletions app/models/license.rb
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ class License < ApplicationRecord
:renew_from_expiry?, :renew_from_now?, :renew_from_now_if_expired?,
:supports_token_auth?,
:supports_license_auth?,
:supports_session_auth?,
:supports_mixed_auth?,
:supports_auth?,
:require_heartbeat?,
Expand Down
5 changes: 5 additions & 0 deletions app/models/policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class EmptyPoolError < StandardError; end
AUTHENTICATION_STRATEGIES = %w[
TOKEN
LICENSE
SESSION
MIXED
NONE
].freeze
Expand Down Expand Up @@ -588,6 +589,10 @@ def supports_license_auth?
authentication_strategy == 'LICENSE' || supports_mixed_auth?
end

def supports_session_auth?
authentication_strategy == 'SESSION' || supports_mixed_auth?
end

def supports_mixed_auth?
authentication_strategy == 'MIXED'
end
Expand Down
81 changes: 65 additions & 16 deletions features/api/v1/tokens/sessions.feature
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,11 @@ Feature: Token sessions
Scenario: License validates itself via session authentication (isolated license in isolated env)
Given the current account is "test1"
And the current account has 1 isolated "environment"
And the current account has 1 isolated "license"
And the current account has 1 isolated "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 isolated "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
And I send the following headers:
Expand All @@ -264,7 +268,11 @@ Feature: Token sessions
Scenario: License validates itself via session authentication (shared license in shared env)
Given the current account is "test1"
And the current account has 1 shared "environment"
And the current account has 1 shared "license"
And the current account has 1 shared "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 shared "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
And I send the following headers:
Expand All @@ -282,7 +290,11 @@ Feature: Token sessions
Scenario: License validates itself via session authentication (global license in isolated env)
Given the current account is "test1"
And the current account has 1 isolated "environment"
And the current account has 1 global "license"
And the current account has 1 global "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 global "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
And I send the following headers:
Expand All @@ -300,7 +312,11 @@ Feature: Token sessions
Scenario: License validates itself via session authentication (global license in shared env)
Given the current account is "test1"
And the current account has 1 shared "environment"
And the current account has 1 global "license"
And the current account has 1 global "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 global "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
And I send the following headers:
Expand All @@ -318,7 +334,11 @@ Feature: Token sessions
Scenario: License validates itself via session authentication (shared license in global env)
Given the current account is "test1"
And the current account has 1 shared "environment"
And the current account has 1 shared "license"
And the current account has 1 shared "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 shared "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
When I send a POST request to "/accounts/test1/licenses/$0/actions/validate"
Expand All @@ -329,7 +349,11 @@ Feature: Token sessions
Given the current account is "test1"
And the current account has 1 isolated "environment"
And the current account has 1 shared "environment"
And the current account has 1 isolated "license"
And the current account has 1 isolated "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 isolated "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
And I send the following headers:
Expand All @@ -347,7 +371,11 @@ Feature: Token sessions
Scenario: License validates itself via session authentication (isolated license in global env)
Given the current account is "test1"
And the current account has 1 isolated "environment"
And the current account has 1 isolated "license"
And the current account has 1 isolated "policy" with the following:
"""
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 isolated "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
When I send a POST request to "/accounts/test1/licenses/$0/actions/validate"
Expand Down Expand Up @@ -463,11 +491,25 @@ Feature: Token sessions
And the response headers should contain "Set-Cookie" with an expired "session_id" cookie
Then the response status should be "403"

Scenario: License validates their key via session authentication (license auth strategy)
Scenario: License validates their key via session authentication (session auth strategy)
Given the current account is "test1"
And the current account has 1 "policy" with the following:
"""
{ "authenticationStrategy": "LICENSE" }
{ "authenticationStrategy": "SESSION" }
"""
And the current account has 1 "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
When I send a POST request to "/accounts/test1/licenses/$0/actions/validate"
Then the response status should be "200"
And the response headers should not contain "Set-Cookie"
And the response body should be a "license"

Scenario: License validates their key via session authentication (token auth strategy)
Given the current account is "test1"
And the current account has 1 "policy" with the following:
"""
{ "authenticationStrategy": "TOKEN" }
"""
And the current account has 1 "license" for the last "policy"
And I am a license of account "test1"
Expand All @@ -479,24 +521,31 @@ Feature: Token sessions
"""
{
"title": "Access denied",
"detail": "Session token authentication is not allowed by policy",
"detail": "Session authentication is not allowed by policy",
"code": "SESSION_NOT_ALLOWED"
}
"""

Scenario: License validates their key via session authentication (token auth strategy)
Scenario: License validates their key via session authentication (license auth strategy)
Given the current account is "test1"
And the current account has 1 "policy" with the following:
"""
{ "authenticationStrategy": "TOKEN" }
{ "authenticationStrategy": "LICENSE" }
"""
And the current account has 1 "license" for the last "policy"
And I am a license of account "test1"
And I authenticate with a session
When I send a POST request to "/accounts/test1/licenses/$0/actions/validate"
Then the response status should be "200"
And the response headers should not contain "Set-Cookie"
And the response body should be a "license"
Then the response status should be "403"
And the response headers should contain "Set-Cookie" with an expired "session_id" cookie
And the first error should have the following properties:
"""
{
"title": "Access denied",
"detail": "Session authentication is not allowed by policy",
"code": "SESSION_NOT_ALLOWED"
}
"""

Scenario: License validates a key via session authentication (mixed auth strategy)
Given the current account is "test1"
Expand Down Expand Up @@ -528,7 +577,7 @@ Feature: Token sessions
"""
{
"title": "Access denied",
"detail": "Session token authentication is not allowed by policy",
"detail": "Session authentication is not allowed by policy",
"code": "SESSION_NOT_ALLOWED"
}
"""
Expand Down

0 comments on commit 91d6845

Please sign in to comment.