Skip to content
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

外部サービスで BootCamp ログインができるようにした(OAuth2 Providerの機能実装) #8250

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ gem 'data_migrate'
gem 'diffy'
gem 'discord-notifier'
gem 'discordrb', '~> 3.5', require: false
gem 'doorkeeper'
gem 'good_job', '~> 3.14', github: 'komagata/good_job'
gem 'google-cloud-storage', '~> 1.25', require: false
gem 'holiday_jp'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ GEM
rest-client (>= 2.0.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.8.0)
railties (>= 5)
erubi (1.12.0)
et-orbi (1.2.11)
tzinfo
Expand Down Expand Up @@ -621,6 +623,7 @@ DEPENDENCIES
diffy
discord-notifier
discordrb (~> 3.5)
doorkeeper
foreman
good_job (~> 3.14)!
google-cloud-storage (~> 1.25)
Expand Down
9 changes: 7 additions & 2 deletions app/controllers/api/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

class API::UsersController < API::BaseController
before_action :set_user, only: %i[show update]
before_action :require_login_for_api
before_action :require_login_for_api, except: :show
before_action :doorkeeper_authorize!, only: :show
PAGER_NUMBER = 24

def index
Expand Down Expand Up @@ -72,7 +73,11 @@ def target_users
end

def set_user
@user = User.find(params[:id])
@user = if params[:id] == 'show'
User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
else
User.find(params[:id])
end
end

def user_params
Expand Down
10 changes: 10 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@ class User < ApplicationRecord
through: :regular_event_participations,
source: :regular_event

has_many :access_grants,
class_name: 'Doorkeeper::AccessGrant',
foreign_key: :resource_owner_id,
dependent: :delete_all

has_many :access_tokens,
class_name: 'Doorkeeper::AccessToken',
foreign_key: :resource_owner_id,
dependent: :delete_all

has_one_attached :avatar
has_one_attached :profile_image

Expand Down
21 changes: 21 additions & 0 deletions config/initializers/doorkeeper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

Doorkeeper.configure do
orm :active_record
resource_owner_authenticator do
current_user || redirect_to(login_path)
end

admin_authenticator do
if current_user
redirect_to root_path, alert: '管理者としてログインしてください' unless current_user.admin?
else
redirect_to login_path
end
end

# デフォルトのスコープを read に設定
# これにより承認されたアプリケーションは API から公開データの「読み取り」が可能
default_scopes :read
enforce_configured_scopes
end
1 change: 1 addition & 0 deletions config/routes/api.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

Rails.application.routes.draw do
use_doorkeeper
namespace 'api' do
namespace 'admin' do
resource :count, controller: 'count', only: %i(show)
Expand Down
69 changes: 69 additions & 0 deletions db/migrate/20241209132613_create_doorkeeper_tables.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

class CreateDoorkeeperTables < ActiveRecord::Migration[6.1]
def change
create_table :oauth_applications do |t|
t.string :name, null: false
t.string :uid, null: false
t.string :secret, null: false
t.text :redirect_uri, null: false
t.string :scopes, null: false, default: ''
t.boolean :confidential, null: false, default: true
t.timestamps null: false
end

add_index :oauth_applications, :uid, unique: true

create_table :oauth_access_grants do |t|
t.references :resource_owner, null: false
t.references :application, null: false
t.string :token, null: false
t.integer :expires_in, null: false
t.text :redirect_uri, null: false
t.string :scopes, null: false, default: ''
t.datetime :created_at, null: false
t.datetime :revoked_at
end

add_index :oauth_access_grants, :token, unique: true
add_foreign_key(
:oauth_access_grants,
:oauth_applications,
column: :application_id
)

create_table :oauth_access_tokens do |t|
t.references :resource_owner, index: true
t.references :application, null: false
t.string :token, null: false

t.string :refresh_token
t.integer :expires_in
t.string :scopes
t.datetime :created_at, null: false
t.datetime :revoked_at
t.string :previous_refresh_token, null: false, default: ""
end

add_index :oauth_access_tokens, :token, unique: true

# See https://github.com/doorkeeper-gem/doorkeeper/issues/1592
if ActiveRecord::Base.connection.adapter_name == "SQLServer"
execute <<~SQL.squish
CREATE UNIQUE NONCLUSTERED INDEX index_oauth_access_tokens_on_refresh_token ON oauth_access_tokens(refresh_token)
WHERE refresh_token IS NOT NULL
SQL
else
add_index :oauth_access_tokens, :refresh_token, unique: true
end

add_foreign_key(
:oauth_access_tokens,
:oauth_applications,
column: :application_id
)

add_foreign_key :oauth_access_grants, :users, column: :resource_owner_id
add_foreign_key :oauth_access_tokens, :users, column: :resource_owner_id
end
end
48 changes: 47 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_11_03_082456) do
ActiveRecord::Schema.define(version: 2024_12_09_132613) do

# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
Expand Down Expand Up @@ -454,6 +454,48 @@
t.index ["user_id"], name: "index_notifications_on_user_id"
end

create_table "oauth_access_grants", force: :cascade do |t|
t.bigint "resource_owner_id", null: false
t.bigint "application_id", null: false
t.string "token", null: false
t.integer "expires_in", null: false
t.text "redirect_uri", null: false
t.string "scopes", default: "", null: false
t.datetime "created_at", null: false
t.datetime "revoked_at"
t.index ["application_id"], name: "index_oauth_access_grants_on_application_id"
t.index ["resource_owner_id"], name: "index_oauth_access_grants_on_resource_owner_id"
t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true
end

create_table "oauth_access_tokens", force: :cascade do |t|
t.bigint "resource_owner_id"
t.bigint "application_id", null: false
t.string "token", null: false
t.string "refresh_token"
t.integer "expires_in"
t.string "scopes"
t.datetime "created_at", null: false
t.datetime "revoked_at"
t.string "previous_refresh_token", default: "", null: false
t.index ["application_id"], name: "index_oauth_access_tokens_on_application_id"
t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id"
t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true
end

create_table "oauth_applications", force: :cascade do |t|
t.string "name", null: false
t.string "uid", null: false
t.string "secret", null: false
t.text "redirect_uri", null: false
t.string "scopes", default: "", null: false
t.boolean "confidential", default: true, null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
end

create_table "organizers", force: :cascade do |t|
t.bigint "user_id", null: false
t.bigint "regular_event_id", null: false
Expand Down Expand Up @@ -846,6 +888,10 @@
add_foreign_key "micro_reports", "users"
add_foreign_key "notifications", "users"
add_foreign_key "notifications", "users", column: "sender_id"
add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
add_foreign_key "oauth_access_grants", "users", column: "resource_owner_id"
add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id"
add_foreign_key "organizers", "regular_events"
add_foreign_key "organizers", "users"
add_foreign_key "pages", "practices"
Expand Down