mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-05 20:54:27 +08:00
Merge pull request #1278 from okriuchykhin/ok_SCI_2664
Add user_identities CRUD endpoints, make API V1 togglable [SCI-2664][SCI-2686]
This commit is contained in:
commit
818129df1b
10 changed files with 215 additions and 10 deletions
69
app/controllers/api/v1/user_identities_controller.rb
Normal file
69
app/controllers/api/v1/user_identities_controller.rb
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Api
|
||||||
|
module V1
|
||||||
|
class UserIdentitiesController < BaseController
|
||||||
|
before_action :load_user
|
||||||
|
before_action :load_user_identity, only: %i(show update destroy)
|
||||||
|
|
||||||
|
def index
|
||||||
|
identities =
|
||||||
|
@user.user_identities.page(params[:page]).per(params[:page_size])
|
||||||
|
render json: identities, each_serializer: UserIdentitySerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
identity = @user.user_identities.create!(user_identity_params)
|
||||||
|
render json: identity,
|
||||||
|
serializer: UserIdentitySerializer,
|
||||||
|
status: :created
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
render json: @identity, serializer: UserIdentitySerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@identity.attributes = update_user_identity_params
|
||||||
|
if @identity.changed? && @identity.save!
|
||||||
|
render json: @identity, serializer: UserIdentitySerializer
|
||||||
|
else
|
||||||
|
render body: nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@identity.destroy!
|
||||||
|
render body: nil
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_user
|
||||||
|
@user = current_user if current_user.id == params[:user_id].to_i
|
||||||
|
return render body: nil, status: :forbidden unless @user
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_user_identity
|
||||||
|
@identity = @user.user_identities.find(params[:id].to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_identity_params
|
||||||
|
unless params.require(:data).require(:type) == 'user_identities'
|
||||||
|
raise ActionController::BadRequest,
|
||||||
|
'Wrong object type within parameters'
|
||||||
|
end
|
||||||
|
params.require(:data).require(:attributes)
|
||||||
|
params.permit(data: { attributes: %i(provider uid) })[:data]
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user_identity_params
|
||||||
|
unless params.require(:data).require(:id).to_i == params[:id].to_i
|
||||||
|
raise ActionController::BadRequest,
|
||||||
|
'Object ID mismatch in URL and request body'
|
||||||
|
end
|
||||||
|
user_identity_params
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
class UserIdentity < ActiveRecord::Base
|
class UserIdentity < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
validates :provider, uniqueness: { scope: :user_id }
|
validates :provider, presence: true, uniqueness: { scope: :user_id }
|
||||||
validates :uid, uniqueness: { scope: :provider }
|
validates :uid, presence: true, uniqueness: { scope: :provider }
|
||||||
end
|
end
|
||||||
|
|
7
app/serializers/api/v1/user_identity_serializer.rb
Normal file
7
app/serializers/api/v1/user_identity_serializer.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
module Api
|
||||||
|
module V1
|
||||||
|
class UserIdentitySerializer < ActiveModel::Serializer
|
||||||
|
attributes :provider, :uid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -16,12 +16,14 @@ module Api
|
||||||
attr_accessor :core_api_token_ttl
|
attr_accessor :core_api_token_ttl
|
||||||
attr_accessor :core_api_token_iss
|
attr_accessor :core_api_token_iss
|
||||||
attr_accessor :azure_ad_apps
|
attr_accessor :azure_ad_apps
|
||||||
|
attr_accessor :core_api_v1_preview
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@core_api_sign_alg = 'HS256'
|
@core_api_sign_alg = 'HS256'
|
||||||
@core_api_token_ttl = 30.minutes
|
@core_api_token_ttl = 30.minutes
|
||||||
@core_api_token_iss = 'SciNote'
|
@core_api_token_iss = 'SciNote'
|
||||||
@azure_ad_apps = {}
|
@azure_ad_apps = {}
|
||||||
|
@core_api_v1_preview = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,8 @@ Api.configure do |config|
|
||||||
config.core_api_token_iss = ENV['CORE_API_TOKEN_ISS']
|
config.core_api_token_iss = ENV['CORE_API_TOKEN_ISS']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
config.core_api_v1_preview = true if ENV['CORE_API_V1_PREVIEW']
|
||||||
|
|
||||||
vars = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
|
vars = ENV.select { |name, _| name =~ /^[[:alnum:]]*_AZURE_AD_APP_ID/ }
|
||||||
vars.each do |name, value|
|
vars.each do |name, value|
|
||||||
app_name = name.sub('_AZURE_AD_APP_ID', '')
|
app_name = name.sub('_AZURE_AD_APP_ID', '')
|
||||||
|
|
|
@ -540,14 +540,17 @@ Rails.application.routes.draw do
|
||||||
get 'health', to: 'api#health'
|
get 'health', to: 'api#health'
|
||||||
get 'status', to: 'api#status'
|
get 'status', to: 'api#status'
|
||||||
post 'auth/token', to: 'api#authenticate'
|
post 'auth/token', to: 'api#authenticate'
|
||||||
namespace :v1 do
|
if Api.configuration.core_api_v1_preview
|
||||||
resources :teams, only: %i(index show) do
|
namespace :v1 do
|
||||||
resources :inventories, only: %i(index show) do
|
resources :teams, only: %i(index show) do
|
||||||
get 'columns', to: 'inventory_columns#index'
|
resources :inventories, only: %i(index show) do
|
||||||
get 'items', to: 'inventory_items#index'
|
get 'columns', to: 'inventory_columns#index'
|
||||||
|
get 'items', to: 'inventory_items#index'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
resources :users, only: %i(show) do
|
||||||
|
resources :user_identities, only: %i(index create show update destroy)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
resources :users, only: %i(show) do
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
6
spec/factories/user_identeties.rb
Normal file
6
spec/factories/user_identeties.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
FactoryBot.define do
|
||||||
|
factory :user_identity do
|
||||||
|
uid Faker::Crypto.unique.sha1
|
||||||
|
provider Faker::App.unique.name
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,6 +5,9 @@ require 'database_cleaner'
|
||||||
require 'devise'
|
require 'devise'
|
||||||
require_relative 'support/controller_macros'
|
require_relative 'support/controller_macros'
|
||||||
ENV['RAILS_ENV'] = 'test'
|
ENV['RAILS_ENV'] = 'test'
|
||||||
|
|
||||||
|
ENV['CORE_API_V1_PREVIEW'] = 'true'
|
||||||
|
|
||||||
require File.expand_path('../../config/environment', __FILE__)
|
require File.expand_path('../../config/environment', __FILE__)
|
||||||
# Prevent database truncation if the environment is production
|
# Prevent database truncation if the environment is production
|
||||||
abort('The Rails environment is running in production mode!') if Rails.env.production?
|
abort('The Rails environment is running in production mode!') if Rails.env.production?
|
||||||
|
|
|
@ -30,7 +30,7 @@ RSpec.describe 'Api::V1::UsersController', type: :request do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'When invalid request, requested user in not member of the same teams' do
|
it 'When invalid request, requested user is not member of the same teams' do
|
||||||
hash_body = nil
|
hash_body = nil
|
||||||
get api_v1_user_path(id: @user3.id), headers: @valid_headers
|
get api_v1_user_path(id: @user3.id), headers: @valid_headers
|
||||||
expect(response).to have_http_status(403)
|
expect(response).to have_http_status(403)
|
||||||
|
|
113
spec/requests/api/v1/users_identeties_controller_spec.rb
Normal file
113
spec/requests/api/v1/users_identeties_controller_spec.rb
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Api::V1::UsersIdentitiesController', type: :request do
|
||||||
|
before :all do
|
||||||
|
@user1 = create(:user, email: Faker::Internet.unique.email)
|
||||||
|
@user2 = create(:user, email: Faker::Internet.unique.email)
|
||||||
|
create(:user_identity, user: @user1,
|
||||||
|
uid: Faker::Crypto.unique.sha1, provider: Faker::App.unique.name)
|
||||||
|
@valid_headers =
|
||||||
|
{ 'Authorization': 'Bearer ' + generate_token(@user1.id) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET user_identities, #index' do
|
||||||
|
it 'When valid request, requested identities for current user' do
|
||||||
|
hash_body = nil
|
||||||
|
get api_v1_user_user_identities_path(user_id: @user1.id),
|
||||||
|
headers: @valid_headers
|
||||||
|
expect { hash_body = json }.not_to raise_exception
|
||||||
|
expect(hash_body[:data]).to match(
|
||||||
|
ActiveModelSerializers::SerializableResource
|
||||||
|
.new(@user1.user_identities,
|
||||||
|
each_serializer: Api::V1::UserIdentitySerializer)
|
||||||
|
.as_json[:data]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'When invalid request, requested user is not signed in user' do
|
||||||
|
hash_body = nil
|
||||||
|
get api_v1_user_user_identities_path(user_id: @user2.id),
|
||||||
|
headers: @valid_headers
|
||||||
|
expect(response).to have_http_status(403)
|
||||||
|
expect(hash_body).to match(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'When invalid request, non existing user' do
|
||||||
|
hash_body = nil
|
||||||
|
get api_v1_user_user_identities_path(user_id: 123),
|
||||||
|
headers: @valid_headers
|
||||||
|
expect(response).to have_http_status(403)
|
||||||
|
expect(hash_body).to match(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'POST user_identities, #create' do
|
||||||
|
it 'When valid request, create new identity for current user' do
|
||||||
|
hash_body = nil
|
||||||
|
post api_v1_user_user_identities_path(user_id: @user1.id),
|
||||||
|
params: {
|
||||||
|
data: { type: 'user_identities',
|
||||||
|
attributes: { uid: Faker::Crypto.unique.sha1,
|
||||||
|
provider: Faker::App.unique.name } }
|
||||||
|
},
|
||||||
|
headers: @valid_headers
|
||||||
|
expect { hash_body = json }.not_to raise_exception
|
||||||
|
expect(hash_body[:data]).to match(
|
||||||
|
ActiveModelSerializers::SerializableResource
|
||||||
|
.new(@user1.user_identities.order(:id).last,
|
||||||
|
serializer: Api::V1::UserIdentitySerializer)
|
||||||
|
.as_json[:data]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'GET user_identity, #show' do
|
||||||
|
it 'When valid request, requested specific identity for current user' do
|
||||||
|
hash_body = nil
|
||||||
|
get api_v1_user_user_identity_path(
|
||||||
|
user_id: @user1.id, id: @user1.user_identities.order(:id).last
|
||||||
|
), headers: @valid_headers
|
||||||
|
expect { hash_body = json }.not_to raise_exception
|
||||||
|
expect(hash_body[:data]).to match(
|
||||||
|
ActiveModelSerializers::SerializableResource
|
||||||
|
.new(@user1.user_identities.order(:id).last,
|
||||||
|
serializer: Api::V1::UserIdentitySerializer)
|
||||||
|
.as_json[:data]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PUT user_identities, #update' do
|
||||||
|
it 'When valid request, update identity for current user' do
|
||||||
|
hash_body = nil
|
||||||
|
put api_v1_user_user_identity_path(user_id: @user1.id,
|
||||||
|
id: @user1.user_identities.order(:id).last),
|
||||||
|
params: {
|
||||||
|
data: { id: @user1.user_identities.order(:id).last.id,
|
||||||
|
type: 'user_identities',
|
||||||
|
attributes: { uid: Faker::Crypto.unique.sha1 } }
|
||||||
|
},
|
||||||
|
headers: @valid_headers
|
||||||
|
expect { hash_body = json }.not_to raise_exception
|
||||||
|
expect(hash_body[:data]).to match(
|
||||||
|
ActiveModelSerializers::SerializableResource
|
||||||
|
.new(@user1.user_identities.order(:id).last,
|
||||||
|
serializer: Api::V1::UserIdentitySerializer)
|
||||||
|
.as_json[:data]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'DELETE user_identity, #destroy' do
|
||||||
|
it 'When valid request, destroy specified identity for current user' do
|
||||||
|
identity = @user1.user_identities.order(:id).last
|
||||||
|
delete api_v1_user_user_identity_path(user_id: @user1.id, id: identity),
|
||||||
|
headers: @valid_headers
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
expect(response.body).to eq('')
|
||||||
|
expect(UserIdentity.find_by_id(identity.id)).to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue