Skip to content

Api key implementation #466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
636367a
Implementing search feature
benoitlx May 29, 2024
d390724
add apikey controller
AliasXoX Jun 2, 2024
55ab055
adding duration test the 31 of month #issue-2328471615
benoitlx Jun 2, 2024
3b2c707
add form and create feature for ApiKey
AliasXoX Jun 3, 2024
9cfb6ee
add apikey route
AliasXoX Jun 5, 2024
cf14ca4
add new page and functionnal form to add api key
AliasXoX Jun 5, 2024
98e5f38
delete api key create view
AliasXoX Jun 5, 2024
d46f1d1
deleted function in api key helper
AliasXoX Jun 5, 2024
a24f1f9
add first tests
AliasXoX Jun 5, 2024
99385e2
test added for api key | checks if it can create an ApiKey
AliasXoX Jun 5, 2024
62ef0c7
New page for creating api keys
AliasXoX Jun 7, 2024
a814f92
add tests for api key index and destroy actions
AliasXoX Jun 7, 2024
896d616
add fixture for api key
AliasXoX Jun 7, 2024
0a84054
adding access via api authentication
AliasXoX Jun 14, 2024
0e60fad
oups
AliasXoX Jun 14, 2024
5be2472
adding cancancan abilities to api authentication
AliasXoX Jun 14, 2024
be2b48a
oups 2
AliasXoX Jun 14, 2024
3b22322
adding documentation
AliasXoX Jun 16, 2024
c94ec41
adding hashed api keys
AliasXoX Jun 17, 2024
5823b20
really hashing the keys
AliasXoX Jun 17, 2024
7007ebc
don't really know what's going on but tests finally passed
AliasXoX Jun 17, 2024
543e5ad
adding credentials for test environment
AliasXoX Jun 30, 2024
23f2551
Yes
AliasXoX Jun 30, 2024
b912261
Merge branch 'master' of https://github.com/rezoleo/lea5
AliasXoX Jun 30, 2024
a6b181d
test credentials are public
AliasXoX Jun 30, 2024
2f19aa3
adding tests
AliasXoX Jul 2, 2024
bc914f9
Branch API_Key_implementation up to date with master
AliasXoX Jul 2, 2024
fd171e1
adding locals
AliasXoX Jul 2, 2024
2431af6
adding locals
AliasXoX Jul 2, 2024
8e7d33f
adding locals
AliasXoX Jul 2, 2024
c6258a9
adding tests to check rights for api keys
AliasXoX Jul 3, 2024
0a5fde7
adding authorizations tests
AliasXoX Jul 3, 2024
2917a3c
adding test for a session opened by an api key authentication
AliasXoX Jul 3, 2024
3587ade
adding tests
AliasXoX Jul 3, 2024
862cab8
creation of /api endpoint
AliasXoX Oct 26, 2024
f403dda
adding machines to /api scope & reformating api keys jbuilder view
AliasXoX Oct 26, 2024
5737cc0
Merge branch 'master' of https://github.com/rezoleo/lea5
AliasXoX Oct 26, 2024
a89d1cd
Merge branch 'master' into API_Key_implementation
AliasXoX Oct 26, 2024
d1c5a4c
Rubocop...
AliasXoX Oct 26, 2024
f79467a
Rearranging api files
AliasXoX Jan 24, 2025
351eb39
Adding tests, removing artifacts and updating routes for api keys
AliasXoX Apr 9, 2025
c14bb3f
Merge branch 'master' of https://github.com/rezoleo/lea5
AliasXoX Apr 9, 2025
7fc0a58
Merge branch 'master' into API_Key_implementation
AliasXoX Apr 9, 2025
b8f1eb2
adding and formatting tests and finalizing authorizations for api keys
AliasXoX Apr 9, 2025
4a3ea29
Merge branch 'master' of https://github.com/rezoleo/lea5
AliasXoX Apr 11, 2025
5a732cb
Merge branch 'master' into API_Key_implementation
AliasXoX Apr 11, 2025
ad04504
organizing files
AliasXoX Apr 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/abilities/api_key_ability.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class ApiKeyAbility
include CanCan::Ability
def initialize(api_key) # rubocop:disable Lint/UnusedMethodArgument
can :read, :all
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need in a near future to refine the permissions of each key, maybe by listing all the endpoints when creating one and let the user select which he wants the bearer to access (read, create, update, destroy), and change the permissions in the edit view.

end
end
2 changes: 1 addition & 1 deletion app/models/ability.rb → app/abilities/user_ability.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class Ability
class UserAbility
include CanCan::Ability

def initialize(user)
Expand Down
47 changes: 47 additions & 0 deletions app/controllers/api_keys_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

class ApiKeysController < ApplicationController
include ApiKeyAuthenticatable
include SessionsHelper

# Require token authentication for index

def index
@api_keys = ApiKey.accessible_by(current_ability)
authorize! :index, @api_keys
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: differs from how we manage index in user_controller

end

def new
@api_key = ApiKey.new
authorize! :new, @api_key
end

def create
@api_key = ApiKey.new(api_key_params)
authorize! :create, @api_key
respond_to do |format|
if @api_key.save
format.html do
flash[:success] = "ApiKey added! It is #{@api_key.key}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass the token separately in a custom flash key, that way we can style it nicely in the message (use a fixed-width font...) or maybe even add some Javascript to copy it. Rough example:

flash[:new_api_key] = @api_key.key
<% if flash[:new_api_key] %>
  <p>Api key created! It will only be displayed once, so copy it now! <code><%= flash[:new_api_key] %></code></p>
<% end %>

(https://guides.rubyonrails.org/action_controller_overview.html#the-flash)

redirect_to api_keys_url
end
else
format.html { render 'new', status: :unprocessable_entity }
end
end
end

def destroy
@api_key = ApiKey.find(params[:id])
authorize! :destroy, @api_key
@api_key.destroy
flash[:success] = 'ApiKey deleted!'
redirect_to api_keys_url
end

private

def api_key_params
params.require(:api_key).permit(:bearer_name)
end
end
8 changes: 8 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ class ApplicationController < ActionController::Base

before_action :still_authenticated?

def current_ability
@current_ability ||= if session[:api_key_id].nil?
UserAbility.new(current_user)
else
ApiKeyAbility.new(current_bearer)
end
end

private

def still_authenticated?
Expand Down
20 changes: 20 additions & 0 deletions app/controllers/concerns/api_key_authenticatable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module ApiKeyAuthenticatable
extend ActiveSupport::Concern

include ActionController::HttpAuthentication::Basic::ControllerMethods
include ActionController::HttpAuthentication::Token::ControllerMethods

attr_reader :current_api_key, :current_bearer

private

attr_writer :current_api_key, :current_bearer

def authenticator(http_token)
@current_api_key = ApiKey.authenticate_by_token! http_token

current_api_key
end
end
15 changes: 11 additions & 4 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# frozen_string_literal: true

class SessionsController < ApplicationController
include ApiKeyAuthenticatable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
include ApiKeyAuthenticatable

I'm not sure this is still useful

def create
user = User.upsert_from_auth_hash(request.env['omniauth.auth'])
log_in user
flash[:success] = 'You are now logged in!'
redirect_to user_path user
if request.path == '/auth/api'
current_bearer = authenticate_or_request_with_http_token { |token, _options| authenticator(token) }
log_in_api current_bearer
render json: flash[:success] = 'You are now logged in!'
else
user = User.upsert_from_auth_hash(request.env['omniauth.auth'])
log_in user
flash[:success] = 'You are now logged in!'
redirect_to user_path user
end
end

def destroy
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/api_keys_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

module ApiKeysHelper
end
15 changes: 14 additions & 1 deletion app/helpers/sessions_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ def current_user
@current_user
end

def current_bearer
return nil if session[:api_key_id].nil?

@current_bearer = ApiKey.find(session[:api_key_id])
@current_bearer
end

def logged_in?
!current_user.nil?
!current_user.nil? || !current_bearer.nil?
end

def log_in(user)
Expand All @@ -20,6 +27,12 @@ def log_in(user)
session[:groups] = user.groups
end

def log_in_api(bearer)
reset_session # For security reasons, we clear the session data before login
session[:api_key_id] = bearer.id
session[:expires_at] = Time.current + SESSION_DURATION_TIME
end

# TODO: also logout of sso
def log_out
reset_session
Expand Down
26 changes: 26 additions & 0 deletions app/models/api_key.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

class ApiKey < ApplicationRecord
HMAC_SECRET_KEY = Rails.application.credentials.api_key_hmac_secret_key!

validates :bearer_name, presence: true, allow_blank: false

before_create :generate_token_hmac_digest

attr_accessor :key
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to have the column name as api_key_digest (or <something>_digest), to highlight that we don't store the raw API key in the database (and communicate to developers when they use this model thatr ApiKey.api_key_digest is not usable on its own). Then the virtual parameter can be api_key (or <something>).

Also stick to one name, between key/api_key, token (in generate_token_hmac_digest) and bearer (in bearer_name).


def self.authenticate_by_token!(key)
digest = OpenSSL::HMAC.hexdigest 'SHA256', HMAC_SECRET_KEY, key

find_by! api_key: digest
end

private

def generate_token_hmac_digest
@key = SecureRandom.hex(32)

digest = OpenSSL::HMAC.hexdigest 'SHA256', HMAC_SECRET_KEY, @key
self.api_key = digest
end
end
11 changes: 11 additions & 0 deletions app/views/api_keys/_api_key.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<%# locals: (api_key:) -%>

<div class="api_key">
<span><%= api_key.bearer_name %></span>
<span><%=api_key.created_at %></span>
<% if can?(:destroy, api_key) %>
<%= button_to(api_key,method: :delete, data: { turbo_confirm: "Are you sure ?" }, 'aria-label': 'Delete this api key') do %>
<%= svg_icon_tag 'icon_delete' %>
<% end %>
<% end %>
</div>
11 changes: 11 additions & 0 deletions app/views/api_keys/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<%# locals: () -%>

<%= form_with(model: @api_key, class: 'form') do |f| %>
<div>
<%= f.label :bearer_name %>
<%= f.text_field :bearer_name, required: true %>
</div>
<div>
<%= f.submit yield(:button_text) %>
</div>
<% end %>
30 changes: 30 additions & 0 deletions app/views/api_keys/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<%# locals: () -%>

<main>
<div class="container">
<div class="card-details-container card-api-keys card-details-api-keys">
<div class="card card-details">

<div class="card-title">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path xmlns="http://www.w3.org/2000/svg" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0S96 57.3 96 128s57.3 128 128 128zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/>
</svg>
Comment on lines +9 to +11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the icon to the SVG icons file (app/assets/images/icons.svg) and use svg_icon_tag?

<h2>Api Keys</h2>
</div>

<%# Need to pass an instance for an ability with block https://github.com/CanCanCommunity/cancancan/blob/develop/docs/define_abilities_with_blocks.md %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is not required here

Suggested change
<%# Need to pass an instance for an ability with block https://github.com/CanCanCommunity/cancancan/blob/develop/docs/define_abilities_with_blocks.md %>

<% if can?(:create, ApiKey) %>
<%= render "components/buttons/button_primary_create_api", text: "new api key", path: new_api_key_path, aria_label: "Add a new api key" %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you create a new button component, instead of reusing the components/buttons/_button_primary_create.erb partial?

<% end %>

</div>

<div class="divider"></div>
</div>
<div class="card card-api-key card-content">
<div class="card-content-machines">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<div class="card-content-machines">
<div class="card-content-api-keys">

<%= render(@api_keys) || "No bearers of an api key" %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<%= render(@api_keys) || "No bearers of an api key" %>
<%= render(@api_keys) || "No API keys" %>

</div>
</div>
</div>
</main>
5 changes: 5 additions & 0 deletions app/views/api_keys/index.json.jbuilder
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we will in the end remove all JSON responses from the non-api controllers and migrate them to the API namespace (and the API key list already has an API endpoint, created in this Pull Request)

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

# locals: ()

json.array! @api_keys
7 changes: 7 additions & 0 deletions app/views/api_keys/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<%# locals: () -%>

<% provide :button_text, "Create" %>

<h1>ApiKey#new</h1>

<%= render 'form' %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%# locals: (aria_label:, path:, text:) -%>

<%= button_to(path, method: :get, class: "button-primary", 'aria-label': aria_label) do %>
<%= text %>
<%= svg_icon_tag 'icon_plus' %>
<% end %>
3 changes: 3 additions & 0 deletions app/views/layouts/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<li>
<%= link_to "Users", users_path %>
</li>
<li>
<%= link_to "Api Keys", api_keys_url %>
</li>
Comment on lines +13 to +15
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be exposed in the "Admin" area?

<% end %>
</ul>
</nav>
Expand Down
2 changes: 1 addition & 1 deletion config/credentials.yml.enc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
VfC7hNP55EjMyi4vt8jK8lAaRmOkql+wsyAFxSVsQdVT8tbZk1l0dgyELsvoVfHwU9kqzI+wMIFyuH6MoXBhcghZfa6m5g683FM06BDkYPwwDflEVeox0DvWmgGji4qzk3oFe57T9qQT736mz3dWfeQTzvjHnaUpq27gYQTpQHOuELjYwKsMXbFRFiNNMmG5phiG2k0Asc7dqZ8CRPwmhJYPm5aJBc9Bzrz3ebBnhxmZ+JzZ8AsZnnvnAFnylm2jRwgN91kJE9l3fkWVTlF6rm0EoCJ9r3neibTeDu2PtNnkYISp3O7chrBJKo6FS9GFAcOxgkxB8QPiX2TV2s3jPiNyxffxLqUe+jziPP4dDiHdZvKrONIltblTJV2WTzur7/82fCEhQUf2oM7uwavq/yvQNOlay4nUD9TyBGZrs1fyFuulT4Ik2/w4T7usUC6am1xIzB2ITF8IuAgolkT/5EPsIs45gJEpJy9Fqlg1PAv01NN9hhViEl+A--tARvrsUmwyVJ9/XI--ytpULZnEcYeOSqfUYhHAnA==
Ctjn6rzrT8lN8apnt2Pd02BtoVstxzsZTgu7DACFn3A6pXt5rbEb1Z79Tcx5R6t2lB9MbLauB/DwUyS9JdzjzKeQQnGvGDHo0j9/vR1I1N3m3+sEXOuPNihRzzCLgePkh4jYtqNZ8NK1MdjmeG6kfPvB4fYNgLz+LWHudMLDhW98Ee3U6yso/edEMlXolmXyp3C4LeyqW/4qVPqaonUU4LJpYeG+UZndxjifEU8vpIhY4dW10mVpdO5JSnteNbtRBc/ZojuVla69hLEgYyr1uiyoy23ArtztfpyXhZEc6cmuJoXi7gpJd9sIDOZf2/xwasRW1EkI3NgpREj4Gy1t7lSwWLf8vp4j3qpC3/ifnGUUNAoJfBjax18WVOfzf2z051Q1TRN0tMhTknihNcUjAer54eT+JYHv7PLbxACcHs4evI/mnuglBOvI9DggODsUIe/7BqM0oQ0j1lj0/m7FHnexdc8FFHrrZ5IXN3VvZ6E0dAEMXNY8gS66mNjNEf2jfXKRicG/eu0FHYRiR00QgtVKsrggUy5IQnLc5Nj3lAq74Bi53UFDQI/AnaIA6uGQtf2lG3XTyfaadwMA6hOFKSQtVd1/OVJAptFIyJkkMiBiJAcU--rNRzrZK7K/fPFPxc--fNlBrjqZoGt/U748IRtjng==
2 changes: 1 addition & 1 deletion config/credentials/production.yml.enc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
QF2+HIDkGNTPjx81hqlGjQAZyIzZVAp9c7J+dWPqlggPt9u/LWhxWWi6vY7KXGYe3opGafwsWlOgrO0BXtzbOg+RK+Bq9a8rUgsKchqHi44B487Y9/rTvS5bcCTJj5c78AJFdZCsEdOXqUv6khBGHB2i8fGQ5LZyh/SFJhmyt3QqGuL6Ig4MsuD/275o2M94CjrlXT2nNGe6BPl94GurtQv7s67bbgrSy3N2f0Kc+VR4VfrIhTwgkpXxEBv7vk/ok/1WvYpqRbFNuyPhiqkZ6Rj+0oK7JCxtFDL15tBtrIRbdpNuBeWO8BQwf/CfvcgBsJnOGg//LU/AJe+ndMCdUzdfVpuB1QKG4A62lmrLNOEwlw/K3JdPsWqPEh6rSVIr5nAzl4oaxMo0NZs7VK7ZhNpGxkvdNVQEZDxchZkaanQOIFU02240w3nMHYx5aed1MEj2ZpuR26Jg+W85m3K0BvsCDcXAouLTvMCB8kGZ8H6SOWExIdbIhmM3--x6H3t+K9w244qMLp--x+vXvS3cObYjuhqsAb4HYA==
Zmnkjz2oYau2HVmSP0GPQ/fzdTezrNhjFyIiP7okk4UZoOATR8X1mbTwulJF0/1vmtmoCr8jTAPWLfRY+0SwZAidd7yh16vhWCy6mpd5/OMeupQencSQCl3T0wgkkMtIa/J64DbfRav8BPhPBHi4St+1x62FM+WRw0udfj+xA2AUPxtIy/FZXIm+WUHcj6wQKXvIY2xJ1YcpA2WAsmow+1d1Aps1UWzMm0pwysm4SsUCDVS3nloaNTQ25g5+0HZ49biY7nbU6E1IM6dsgwK2/yRrrPxgDpv22L/r3BNp1wv0u4XP5LG+/yfaRfcdaO34WegffGsGEbuBf+hJ/fmxEJ3kq3Uk7DVlbFft94kIfzhHPOU/fi6EX4pWwrS4hExJ43X6/nEMtUY2b6ZXQDLazHv6rI2FcVzsSP+CRQwFc3VU2sjiJbHoe9hh1Jz27d/8rc+BjAwiwwpzZyTsAUlFy92qLZIENJskOhiowZewErJIUmV31L1ImRw/NCCC/Qt+hE8VvTkYmlWFU++9v4wddd5u2GUHzmHh7h7QFUCgKYFeqZiZbi58ihfIn/j7mpdJVk6lc73C+zAMI52rN65bZ6pGySU1/IJMGkhPc181hVC8tdiryw==--ss5nXaT6eOm/wEgh--oHW8aumKNzcCbzU7XFQyXg==
1 change: 1 addition & 0 deletions config/credentials/test.key
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really don't like this 😅 it could be OK to merge the PR as-is, but we will need to quickly find a way to run tests with hardcoded test values that don't need a full encrypted file (same for the development environment, we could use a hardcoded/simpler way to configure the Keycloak config or this HMAC secret without needing a secret key).

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
151fe6f76326223cfb5f7cef5369c504
1 change: 1 addition & 0 deletions config/credentials/test.yml.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mrjWeVMW0ZzGnTS1Yw+YRq/mJUTEyb7vTGp781GRYBv7s4XMK4eRkNrcG3jlb6StbugQFUa3yKSSUac1E/LHrtRgDS8FO7lkN3m3gnD/apzZ6QFQ+ub/Gzhgg9htCB2OSTwKwHINeCuog/wlxeGd3VGon0nNltGlYKv8Fet2W8KyMaOBNSFTwf6zv0jPrke1LRGiqAlNuaA=--w7kZ8Fb41WHlHnQB--mk0Xq4zeXvm7j1VYpZ39jQ==
3 changes: 3 additions & 0 deletions config/initializers/_constants.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# frozen_string_literal: true

# Path to login via api key
AUTH_API_PATH = '/auth/api'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Path to login via api key
AUTH_API_PATH = '/auth/api'

I think it's an artifact of the previous version that uses full connection and not Authorization header

# Path to login via SSO authentication
AUTH_PATH = '/auth/keycloak'

Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
get AUTH_CALLBACK_PATH, to: 'sessions#create', as: 'auth_callback'
get AUTH_API_PATH, to: 'sessions#create', as: 'auth_api'
delete '/logout', to: 'sessions#destroy', as: 'logout'
root 'static_pages#home'

Expand All @@ -13,6 +14,7 @@
resources :free_accesses, shallow: true, except: [:index, :show]
end

resources :api_keys
get '/search', as: 'search', to: 'search#search'

# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
Expand Down
14 changes: 14 additions & 0 deletions db/migrate/20240531163901_api_keys.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

class ApiKeys < ActiveRecord::Migration[7.0]
def change
create_table :api_keys do |t|
t.integer :bearer_id, null: false, index: { unique: true }
t.string :bearer_name, null: false
t.string :api_key, null: false, index: { unique: true }
t.datetime :api_key_start_at, index: { unique: true }

t.timestamps
end
end
end
10 changes: 10 additions & 0 deletions db/migrate/20240602124750_fix_api_key.rb
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the branch is not merged yet, could you combine the migrations in a single one? (to avoid having "migration + fix1 + fix2")

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class FixApiKey < ActiveRecord::Migration[7.0]
def change
change_table :api_keys do |t|
t.remove :api_key_start_at,
type: :datetime
end
end
end
10 changes: 10 additions & 0 deletions db/migrate/20240603090057_fix_api_key_bearer_id.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class FixApiKeyBearerId < ActiveRecord::Migration[7.0]
def change
change_table :api_keys do |t|
t.remove :bearer_id,
type: :integer
end
end
end
14 changes: 11 additions & 3 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading