Skip to content

Commit 00bfb3a

Browse files
authored
feat(auth): remove callbackUrl parameter on authentication and remove forest_agent_url (FOREST_APPLICATION_URL) variable (#582)
1 parent a571c5a commit 00bfb3a

File tree

7 files changed

+47
-62
lines changed

7 files changed

+47
-62
lines changed

app/controllers/forest_liana/authentication_controller.rb

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,30 @@ class AuthenticationController < ForestLiana::BaseController
66
START_AUTHENTICATION_ROUTE = 'authentication'
77
CALLBACK_AUTHENTICATION_ROUTE = 'authentication/callback'
88
LOGOUT_ROUTE = 'authentication/logout'
9-
PUBLIC_ROUTES = [
10-
"/#{START_AUTHENTICATION_ROUTE}",
11-
"/#{CALLBACK_AUTHENTICATION_ROUTE}",
12-
"/#{LOGOUT_ROUTE}",
13-
]
9+
PUBLIC_ROUTES = %W[/#{START_AUTHENTICATION_ROUTE} /#{CALLBACK_AUTHENTICATION_ROUTE} /#{LOGOUT_ROUTE}]
1410

1511
def initialize
1612
@authentication_service = ForestLiana::Authentication.new()
1713
end
18-
19-
def get_callback_url
20-
File.join(ForestLiana.application_url, "/forest/#{CALLBACK_AUTHENTICATION_ROUTE}").to_s
21-
rescue => error
22-
raise "application_url is not valid or not defined" if error.is_a?(ArgumentError)
23-
end
2414

2515
def get_and_check_rendering_id
2616
if !params.has_key?('renderingId')
2717
raise ForestLiana::MESSAGES[:SERVER_TRANSACTION][:MISSING_RENDERING_ID]
2818
end
2919

3020
rendering_id = params[:renderingId]
31-
21+
3222
if !(rendering_id.instance_of?(String) || rendering_id.instance_of?(Numeric)) || (rendering_id.instance_of?(Numeric) && rendering_id.nan?)
3323
raise ForestLiana::MESSAGES[:SERVER_TRANSACTION][:INVALID_RENDERING_ID]
3424
end
3525

3626
return rendering_id.to_i
3727
end
3828

39-
def start_authentication
29+
def start_authentication
4030
begin
4131
rendering_id = get_and_check_rendering_id()
42-
callback_url = get_callback_url()
43-
44-
result = @authentication_service.start_authentication(
45-
callback_url,
46-
{ 'renderingId' => rendering_id },
47-
)
32+
result = @authentication_service.start_authentication({ 'renderingId' => rendering_id })
4833

4934
render json: { authorizationUrl: result['authorization_url']}, status: 200
5035
rescue => error
@@ -55,12 +40,7 @@ def start_authentication
5540

5641
def authentication_callback
5742
begin
58-
callback_url = get_callback_url()
59-
60-
token = @authentication_service.verify_code_and_generate_token(
61-
callback_url,
62-
params,
63-
)
43+
token = @authentication_service.verify_code_and_generate_token(params)
6444

6545
response_body = {
6646
token: token,
@@ -79,7 +59,7 @@ def logout
7959
begin
8060
if cookies.has_key?(:forest_session_token)
8161
forest_session_token = cookies[:forest_session_token]
82-
62+
8363
if forest_session_token
8464
response.set_cookie(
8565
'forest_session_token',

app/services/forest_liana/authentication.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
module ForestLiana
22
class Authentication
3-
def start_authentication(redirect_url, state)
4-
client = ForestLiana::OidcClientManager.get_client_for_callback_url(redirect_url)
3+
def start_authentication(state)
4+
client = ForestLiana::OidcClientManager.get_client()
55

66
authorization_url = client.authorization_uri({
77
scope: 'openid email profile',
88
state: state.to_s,
99
})
10-
10+
1111
{ 'authorization_url' => authorization_url }
1212
end
1313

14-
def verify_code_and_generate_token(redirect_url, params)
15-
client = ForestLiana::OidcClientManager.get_client_for_callback_url(redirect_url)
14+
def verify_code_and_generate_token(params)
15+
client = ForestLiana::OidcClientManager.get_client()
1616

1717
rendering_id = parse_state(params['state'])
1818
client.authorization_code = params['code']

app/services/forest_liana/oidc_client_manager.rb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,32 @@
22

33
module ForestLiana
44
class OidcClientManager
5-
def self.get_client_for_callback_url(callback_url)
5+
def self.get_client
66
begin
77
configuration = ForestLiana::OidcConfigurationRetriever.retrieve()
88
if ForestLiana.forest_client_id.nil?
9-
client_data = Rails.cache.read("#{callback_url}-#{ForestLiana.env_secret}-client-data") || nil
9+
client_data = Rails.cache.read("#{ForestLiana.env_secret}-client-data") || nil
1010
if client_data.nil?
1111
client_credentials = ForestLiana::OidcDynamicClientRegistrator.register({
1212
token_endpoint_auth_method: 'none',
13-
redirect_uris: [callback_url],
1413
registration_endpoint: configuration['registration_endpoint']
1514
})
16-
client_data = { :client_id => client_credentials['client_id'], :issuer => configuration['issuer'] }
17-
Rails.cache.write("#{callback_url}-#{ForestLiana.env_secret}-client-data", client_data)
15+
client_data = { :client_id => client_credentials['client_id'], :issuer => configuration['issuer'], :redirect_uri => client_credentials['redirect_uris'][0] }
16+
Rails.cache.write("#{ForestLiana.env_secret}-client-data", client_data)
1817
end
1918
else
20-
client_data = { :client_id => ForestLiana.forest_client_id, :issuer => configuration['issuer'] }
19+
client_data = { :client_id => ForestLiana.forest_client_id, :issuer => configuration['issuer'], :redirect_uri => File.join(ForestLiana.application_url, "/forest/authentication/callback").to_s }
2120
end
2221

2322
OpenIDConnect::Client.new(
2423
identifier: client_data[:client_id],
25-
redirect_uri: callback_url,
24+
redirect_uri: client_data[:redirect_uri],
2625
host: "#{client_data[:issuer].sub(/^https?\:\/\/(www.)?/,'')}",
2726
authorization_endpoint: '/oidc/auth',
2827
token_endpoint: '/oidc/token',
2928
)
3029
rescue => error
31-
Rails.cache.delete("#{callback_url}-#{ForestLiana.env_secret}-client-data")
30+
Rails.cache.delete("#{ForestLiana.env_secret}-client-data")
3231
raise error
3332
end
3433
end

lib/forest_liana/bootstrapper.rb

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,19 @@ def initialize
1818
ForestLiana.auth_secret = ForestLiana.auth_key
1919
end
2020

21-
unless Rails.application.config.action_controller.perform_caching || Rails.env.test? || ForestLiana.forest_client_id
21+
if ForestLiana.forest_client_id
22+
FOREST_LOGGER.warn "DEPRECATION WARNING: The use of " \
23+
"ForestLiana.forest_client_id is deprecated. It's not needed anymore."
24+
end
25+
26+
if Rails.application.secrets.forest_application_url
27+
FOREST_LOGGER.warn "DEPRECATION WARNING: The use of " \
28+
"The secret forest_application_url is deprecated. It's not needed anymore."
29+
end
30+
31+
unless Rails.application.config.action_controller.perform_caching || Rails.env.test?
2232
FOREST_LOGGER.error "You need to enable caching on your environment to use Forest Admin.\n" \
23-
"For a development environment, run: `rails dev:cache`\n" \
24-
"Or setup a static forest_client_id by following this part of the documentation:\n" \
25-
"https://docs.forestadmin.com/documentation/how-tos/maintain/upgrade-notes-rails/upgrade-to-v6#setup-a-static-clientid"
33+
"For a development environment, run: `rails dev:cache`"
2634
end
2735

2836
fetch_models

lib/generators/forest_liana/install_generator.rb

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ class InstallGenerator < Rails::Generators::Base
55
desc 'Forest Rails Liana installation generator'
66

77
argument :env_secret, type: :string, required: true, desc: 'required', banner: 'env_secret'
8-
argument :application_url, type: :string, required: false, desc: 'optional', banner: 'application_url', default: 'http://localhost:3000'
98

109
def install
1110
if ForestLiana.env_secret.present?
@@ -28,42 +27,35 @@ def install
2827
if File.exist? 'config/secrets.yml'
2928
inject_into_file 'config/secrets.yml', after: "development:\n" do
3029
" forest_env_secret: #{env_secret}\n" +
31-
" forest_auth_secret: #{auth_secret}\n" +
32-
" forest_application_url: #{application_url}\n"
30+
" forest_auth_secret: #{auth_secret}\n"
3331
end
3432

3533
inject_into_file 'config/secrets.yml', after: "staging:\n", force: true do
3634
" forest_env_secret: <%= ENV[\"FOREST_ENV_SECRET\"] %>\n" +
37-
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n" +
38-
" forest_application_url: <%= ENV[\"FOREST_APPLICATION_URL\"] %>\n"
35+
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n"
3936
end
4037

4138
inject_into_file 'config/secrets.yml', after: "production:\n", force: true do
4239
" forest_env_secret: <%= ENV[\"FOREST_ENV_SECRET\"] %>\n" +
43-
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n" +
44-
" forest_application_url: <%= ENV[\"FOREST_APPLICATION_URL\"] %>\n"
40+
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n"
4541
end
4642
else
4743
create_file 'config/secrets.yml' do
4844
"development:\n" +
4945
" forest_env_secret: #{env_secret}\n" +
5046
" forest_auth_secret: #{auth_secret}\n" +
51-
" forest_application_url: #{application_url}\n" +
5247
"staging:\n" +
5348
" forest_env_secret: <%= ENV[\"FOREST_ENV_SECRET\"] %>\n" +
5449
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n" +
55-
" forest_application_url: <%= ENV[\"FOREST_APPLICATION_URL\"] %>\n" +
5650
"production:\n" +
5751
" forest_env_secret: <%= ENV[\"FOREST_ENV_SECRET\"] %>\n" +
58-
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n" +
59-
" forest_application_url: <%= ENV[\"FOREST_APPLICATION_URL\"] %>\n"
52+
" forest_auth_secret: <%= ENV[\"FOREST_AUTH_SECRET\"] %>\n"
6053
end
6154
end
6255

6356
initializer 'forest_liana.rb' do
6457
"ForestLiana.env_secret = Rails.application.secrets.forest_env_secret" +
65-
"\nForestLiana.auth_secret = Rails.application.secrets.forest_auth_secret" +
66-
"\nForestLiana.application_url = Rails.application.secrets.forest_application_url"
58+
"\nForestLiana.auth_secret = Rails.application.secrets.forest_auth_secret"
6759
end
6860
end
6961
end

lib/tasks/clear_oidc_data.rake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace :forest do
2+
desc "Clear the OIDC data cache key"
3+
task clear: :environment do
4+
Rails.cache.delete("#{ForestLiana.env_secret}-client-data")
5+
end
6+
end

spec/requests/authentications_spec.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,19 @@
1414
}', :symbolize_names => false)
1515
}
1616
allow(ForestLiana::ForestApiRequester).to receive(:post) {
17-
instance_double(HTTParty::Response, body: '{ "client_id": "random_id" }', code: 201)
17+
instance_double(HTTParty::Response, body: '{ "client_id": "random_id", "redirect_uris": ["http://localhost:3000/forest/authentication/callback"] }', code: 201)
1818
}
1919
allow_any_instance_of(OpenIDConnect::Client).to receive(:access_token!) {
2020
OpenIDConnect::AccessToken.new(access_token: 'THE-ACCESS-TOKEN', client: instance_double(OpenIDConnect::Client))
2121
}
2222
end
2323

2424
after do
25-
Rails.cache.delete(URI.join(ForestLiana.application_url, ForestLiana::Engine.routes.url_helpers.authentication_callback_path).to_s)
25+
Rails.cache.delete("#{ForestLiana.env_secret}-client-data")
2626
end
2727

2828
describe "POST /authentication" do
29-
before() do
29+
before() do
3030
post ForestLiana::Engine.routes.url_helpers.authentication_path, params: '{"renderingId":"42"}', headers: {
3131
'Accept' => 'application/json',
3232
'Content-Type' => 'application/json',
@@ -44,10 +44,10 @@
4444
end
4545

4646
describe "GET /authentication/callback" do
47-
before() do
47+
before() do
4848
response = '{"data":{"id":666,"attributes":{"first_name":"Alice","last_name":"Doe","email":"alice@forestadmin.com","teams":[1,2,3],"role":"Test","tags":[{"key":"city","value":"Paris"}]}}}'
4949
allow(ForestLiana::ForestApiRequester).to receive(:get).with(
50-
"/liana/v2/renderings/42/authorization", { :headers => { "forest-token" => "THE-ACCESS-TOKEN" }, :query=> {} }
50+
"/liana/v2/renderings/42/authorization", { :headers => { "forest-token" => "THE-ACCESS-TOKEN" }, :query => {} }
5151
).and_return(
5252
instance_double(HTTParty::Response, :body => response, :code => 200)
5353
)
@@ -86,7 +86,7 @@
8686
end
8787

8888
describe "POST /authentication/logout" do
89-
before() do
89+
before() do
9090
post ForestLiana::Engine.routes.url_helpers.authentication_logout_path, params: { :renderingId => 42 }, :headers => headers
9191
end
9292

0 commit comments

Comments
 (0)