rails_keycloak_authorization 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3a5679ea27b8534269d023d54c80e29d622605845cdf0d078fdc5a79acbe817
4
- data.tar.gz: 0f14c1867168d7f139fa574642ce54058e9cb438f18d0c35eab9f77ed328399b
3
+ metadata.gz: 122890dbd82fc49d04abde438a1fb4b30861a5c87160b799516ebd6400ad6707
4
+ data.tar.gz: 2cf108a6f02b11e030e68ee800c8b9f8917d436703d8719a1732f4968dda8dd6
5
5
  SHA512:
6
- metadata.gz: 55c352bccb846e025ed0c12cd31cac15931407ca7d149884d205be532c50dfd46f4983b4e1a12bdbc1b6de8e9e1ce9c2aa4ef8248716517dccdbdd5fc40468b5
7
- data.tar.gz: 305d5263ae016648cd04068ab2f5edeb125b336016ee1a2ef2482f6d4f0808347ff2eab7c897caddafe43381160c4591354c3033097da173bb4230a73675b500
6
+ metadata.gz: fdddaca8f60e5260114f3e10ef86d73d45d6bc38b4080626c3ea3463828048e83cd407ab5718469252b776a80ef848acbb3ba56af97dc1a5565563c0992446c4
7
+ data.tar.gz: 9eec75e13109fa1579c74d54b89e0117d48aba087dd0bd332eafc6c2ba10d6d207b1597c00397cb3eb8c64bd7d2000b4a1eadab195e30f51051bd84130741145
data/README.md CHANGED
@@ -53,20 +53,28 @@ sequenceDiagram
53
53
  In order to use this gem, you need to configure it in an initializer file. You can create a new file in `config/initializers/rails_keycloak_authorization.rb` with the following content:
54
54
 
55
55
  ```ruby
56
- # The Keycloak realm
57
- RailsKeycloakAuthorization.keycloak_realm = ENV.fetch("KEYCLOAK_AUTH_CLIENT_REALM_NAME", "dummy")
58
- # The client id in the realm
59
- RailsKeycloakAuthorization.client_id = ENV.fetch("KEYCLOAK_AUTH_CLIENT_ID", "dummy-client")
60
- # Keycloak server url
61
- RailsKeycloakAuthorization.keycloak_server_url = ENV.fetch("KEYCLOAK_SERVER_URL", "http://localhost:8080")
62
- # Patterns that are protected by the middleware, Array of regular-expressions.
63
- RailsKeycloakAuthorization.match_patterns = [
56
+ RailsKeycloakAuthorization.keycloak_auth_client_realm_name = ENV.fetch("KEYCLOAK_AUTH_CLIENT_REALM_NAME", "dummy")
57
+ RailsKeycloakAuthorization.keycloak_auth_client_id = ENV.fetch("KEYCLOAK_AUTH_CLIENT_ID", "dummy-client")
58
+ RailsKeycloakAuthorization.keycloak_server_url = ENV.fetch("KEYCLOAK_SERVER_URL", "http://localhost:8080")
59
+ RailsKeycloakAuthorization.keycloak_server_domain = ENV.fetch("KEYCLOAK_ADMIN_SERVER_DOMAIN", "localhost")
60
+ RailsKeycloakAuthorization.keycloak_admin_realm_name = ENV.fetch("KEYCLOAK_ADMIN_REALM_NAME", "master")
61
+ RailsKeycloakAuthorization.keycloak_admin_client_id = ENV.fetch("KEYCLOAK_ADMIN_CLIENT_ID", "keycloak-admin")
62
+ RailsKeycloakAuthorization.keycloak_admin_client_secret = ENV.fetch("KEYCLOAK_ADMIN_CLIENT_SECRET", "keycloak-admin-client-secret-xxx")
63
+ RailsKeycloakAuthorization.match_patterns = [
64
64
  /^\/organizations(\.json)?/,
65
65
  /^\/api/,
66
66
  /internal/
67
67
  ]
68
68
  ```
69
69
 
70
+ Add the route to the UI helper `config/routes.rb`:
71
+
72
+ ```
73
+ # make sure to change the constraint to suite your security
74
+ mount RailsKeycloakAuthorization::Engine, at: "/rka", constraints: lambda { |request| request.remote_ip == "127.0.0.1" }
75
+ ```
76
+
77
+
70
78
  ## How to easily test it?
71
79
 
72
80
  Create development environment with Keycloak and Tofu:
@@ -5,28 +5,25 @@ module RailsKeycloakAuthorization
5
5
  before_action :keycloak_admin_configure
6
6
  end
7
7
 
8
- private
9
-
10
-
11
-
12
-
13
-
8
+
14
9
  def realm_name
15
- ENV.fetch('KEYCLOAK_AUTH_CLIENT_REALM_NAME')
10
+ RailsKeycloakAuthorization.keycloak_auth_client_realm_name
16
11
  end
12
+ private
13
+
17
14
 
18
15
  def openid_client
19
- KeycloakAdmin.realm(realm_name).clients.find_by_client_id(ENV["KEYCLOAK_AUTH_CLIENT_ID"])
16
+ KeycloakAdmin.realm(realm_name).clients.find_by_client_id(RailsKeycloakAuthorization.keycloak_auth_client_id)
20
17
  end
21
18
 
22
19
  def keycloak_admin_configure
23
20
  KeycloakAdmin.configure do |config|
24
21
  config.use_service_account = true
25
- config.server_url = ENV["KEYCLOAK_SERVER_URL"]
26
- config.server_domain = ENV["KEYCLOAK_SERVER_DOMAIN"]
27
- config.client_id = ENV["KEYCLOAK_ADMIN_CLIENT_ID"]
28
- config.client_realm_name = ENV["KEYCLOAK_ADMIN_REALM_NAME"]
29
- config.client_secret = ENV["KEYCLOAK_ADMIN_CLIENT_SECRET"]
22
+ config.server_url = RailsKeycloakAuthorization.keycloak_server_url
23
+ config.server_domain = RailsKeycloakAuthorization.keycloak_server_domain
24
+ config.client_realm_name = RailsKeycloakAuthorization.keycloak_admin_realm_name
25
+ config.client_id = RailsKeycloakAuthorization.keycloak_admin_client_id
26
+ config.client_secret = RailsKeycloakAuthorization.keycloak_admin_client_secret
30
27
  config.logger = Rails.logger
31
28
  config.rest_client_options = { timeout: 3, verify_ssl: Rails.env.production? }
32
29
  end
@@ -12,7 +12,7 @@ module RailsKeycloakAuthorization
12
12
  end
13
13
 
14
14
  def create
15
- KeycloakAdminRubyAgent.create_keycloak_policy(params[:keycloak_realm_role_id])
15
+ KeycloakAdminRubyAgent.create_keycloak_policy(params[:keycloak_realm_role_id], params[:keycloak_policy_name])
16
16
  redirect_to policies_path
17
17
  end
18
18
  end
@@ -35,11 +35,11 @@ module RailsKeycloakAuthorization
35
35
  .find_by(POLICY_NAME, "role")
36
36
  end
37
37
 
38
- def create_keycloak_policy(keycloak_realm_role_id)
38
+ def create_keycloak_policy(keycloak_realm_role_id, policy_name)
39
39
  KeycloakAdmin
40
40
  .realm(realm_name)
41
41
  .authz_policies(openid_client.id, 'role')
42
- .create!("#{POLICY_NAME}",
42
+ .create!(policy_name,
43
43
  "#{POLICY_NAME} default policy",
44
44
  "role",
45
45
  "POSITIVE",
@@ -100,14 +100,14 @@ module RailsKeycloakAuthorization
100
100
  end
101
101
 
102
102
  def realm_name
103
- ENV.fetch("KEYCLOAK_AUTH_CLIENT_REALM_NAME")
103
+ RailsKeycloakAuthorization.keycloak_auth_client_realm_name
104
104
  end
105
105
 
106
106
  def openid_client
107
107
  KeycloakAdmin
108
108
  .realm(realm_name)
109
109
  .clients
110
- .find_by_client_id(ENV.fetch("KEYCLOAK_AUTH_CLIENT_ID"))
110
+ .find_by_client_id(RailsKeycloakAuthorization.keycloak_auth_client_id)
111
111
  end
112
112
 
113
113
  def resource_type_for_controller
@@ -124,13 +124,13 @@ module RailsKeycloakAuthorization
124
124
  def keycloak_admin_configure
125
125
  KeycloakAdmin.configure do |config|
126
126
  config.use_service_account = true
127
- config.server_url = ENV.fetch("KEYCLOAK_SERVER_URL")
128
- config.server_domain = ENV.fetch("KEYCLOAK_SERVER_DOMAIN")
129
- config.client_id = ENV.fetch("KEYCLOAK_ADMIN_CLIENT_ID")
130
- config.client_realm_name = ENV.fetch("KEYCLOAK_ADMIN_REALM_NAME")
131
- config.client_secret = ENV.fetch("KEYCLOAK_ADMIN_CLIENT_SECRET")
132
- config.logger = Rails.logger
133
- config.rest_client_options = { timeout: 5, verify_ssl: Rails.env.production? }
127
+ config.server_url = RailsKeycloakAuthorization.keycloak_server_url
128
+ config.server_domain = RailsKeycloakAuthorization.keycloak_server_domain
129
+ config.client_realm_name = RailsKeycloakAuthorization.keycloak_admin_realm_name
130
+ config.client_id = RailsKeycloakAuthorization.keycloak_admin_client_id
131
+ config.client_secret = RailsKeycloakAuthorization.keycloak_admin_client_secret
132
+ config.logger = Rails.logger
133
+ config.rest_client_options = { timeout: 3, verify_ssl: Rails.env.production? }
134
134
  end
135
135
  end
136
136
  end
@@ -1,23 +1,34 @@
1
- <h1 class="text-center text-gray-500">Policies</h1>
2
- <% if @policies.empty? %>
3
- <p class="inline">Default Policy for </p>
4
- <form class="inline" hx-post="<%= policies_path %>">
1
+ <div id="policies">
2
+ <h1 class="text-center text-gray-500">Policies</h1>
3
+
4
+ <% @policies.map do |policy| %>
5
+ <div class="mt-2">
6
+ <p>Policy Name: <%= policy.name %></p>
7
+ <p>Policy Roles:</p>
8
+ <% policy.roles.map do |role| %>
9
+ <% realm_role = @realm_roles.first{|rr| rr.id == rold.id } %>
10
+ <ul class="list-disc list-inside">
11
+ <li><%= realm_role.name %></li>
12
+ </ul>
13
+ <% end %>
14
+ </div>
15
+ <% end %>
16
+
17
+ <hr class="mb-6 mt-6"/>
18
+
19
+ <form class="inline" hx-post="<%= policies_path %>" hx-target="#policies">
20
+ <label for="keycloak_policy_name">Name</label>
5
21
  <input id="keycloak_policy_name" name="keycloak_policy_name" value="<%= @default_policy_name %>" type="text">
6
22
  <label for="keycloak_realm_role">Role</label>
7
23
  <select name="keycloak_realm_role_id" hx-indicator=".htmx-indicator">
8
24
  <% @realm_roles.map do |role| %>
9
25
  <option value="<%= role.id %>" <%= role.name.include?("default") ? "selected=selected" : "" %>>
10
- <%= role.name %>
26
+ <%= role.name %>
11
27
  </option>
12
28
  <% end %>
13
29
  </select>
14
30
  <button
15
- class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-3 rounded"
16
- type="submit">Create</button>
31
+ class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-3 rounded"
32
+ type="submit">Create</button>
17
33
  </form>
18
- <% else %>
19
- <div class="text-gray-500">Current Policy</div>
20
- <% @policies.map do |policy| %>
21
- <p><%= policy.name %></p>
22
- <% end %>
23
- <% end %>
34
+ </div>
@@ -1,8 +1,12 @@
1
1
  module RailsKeycloakAuthorization
2
2
  class Engine < ::Rails::Engine
3
+ require 'keycloak-admin'
3
4
  isolate_namespace RailsKeycloakAuthorization
4
5
  initializer "rails_keycloak_authorization.middleware" do |app|
5
6
  app.middleware.use RailsKeycloakAuthorization::Middleware
6
7
  end
8
+ initializer "rails_keycloak_authorization.assets.precompile" do |app|
9
+ app.config.assets.precompile += %w( rails_keycloak_authorization/application.css )
10
+ end
7
11
  end
8
12
  end
@@ -1,3 +1,3 @@
1
1
  module RailsKeycloakAuthorization
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -2,12 +2,14 @@ require "rails_keycloak_authorization/version"
2
2
  require "rails_keycloak_authorization/engine"
3
3
 
4
4
  module RailsKeycloakAuthorization
5
- mattr_accessor :keycloak_realm
6
5
  mattr_accessor :keycloak_server_url
7
- mattr_accessor :keycloak_admin_username
8
- mattr_accessor :keycloak_admin_password
6
+ mattr_accessor :keycloak_server_domain
7
+ mattr_accessor :keycloak_admin_realm_name
8
+ mattr_accessor :keycloak_admin_client_id
9
+ mattr_accessor :keycloak_admin_client_secret
10
+ mattr_accessor :keycloak_auth_client_id
11
+ mattr_accessor :keycloak_auth_client_realm_name
9
12
  mattr_accessor :match_patterns
10
- mattr_accessor :client_id
11
13
 
12
14
  class Middleware
13
15
  def initialize(app)
@@ -36,7 +38,7 @@ module RailsKeycloakAuthorization
36
38
 
37
39
  def authorize!(request_uri, http_authorization)
38
40
  route = Rails.application.routes.recognize_path(request_uri)
39
- uri = uri(RailsKeycloakAuthorization.keycloak_server_url, RailsKeycloakAuthorization.keycloak_realm)
41
+ uri = uri(RailsKeycloakAuthorization.keycloak_server_url, RailsKeycloakAuthorization.keycloak_auth_client_realm_name)
40
42
  request = http_request(uri, http_authorization, route)
41
43
  response = http_client(uri).request(request)
42
44
  response.is_a?(Net::HTTPSuccess)
@@ -49,7 +51,7 @@ module RailsKeycloakAuthorization
49
51
  })
50
52
  permission = "#{route[:controller]}_controller##{route[:action]}"
51
53
  request.body = URI.encode_www_form({
52
- audience: "#{RailsKeycloakAuthorization.client_id}",
54
+ audience: "#{RailsKeycloakAuthorization.keycloak_auth_client_id}",
53
55
  grant_type: grant_type,
54
56
  permission: permission,
55
57
  response_mode: "permissions",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_keycloak_authorization
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mohammed O. Tillawy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-10 00:00:00.000000000 Z
11
+ date: 2024-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails