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

Feature/434 bearer authentication #435

Merged
merged 12 commits into from
Jul 3, 2023
18 changes: 17 additions & 1 deletion core/app/controllers/concerns/uffizzi_core/auth_management.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,23 @@ def signed_in?
end

def current_user
@current_user ||= UffizziCore::User.find_by(id: session[:user_id])
@current_user ||= UffizziCore::User.find_by(id: current_user_id)
end

def auth_token
header = request.headers['Authorization']
header&.split(' ')&.last
end

def current_user_id
return session[:user_id] if session[:user_id].present?
return unless auth_token.present?

decoded_token = UffizziCore::TokenService.decode(auth_token)
return unless decoded_token
return if decoded_token.first['expires_at'] < DateTime.now

decoded_token.first['user_id']
end

def authenticate_request!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
class UffizziCore::Api::Cli::V1::Accounts::ProjectsController < UffizziCore::Api::Cli::V1::Accounts::ApplicationController
before_action :authorize_uffizzi_core_api_cli_v1_accounts_projects

def index
projects = resource_account.projects.active

respond_with projects, each_serializer: UffizziCore::Api::Cli::V1::ShortProjectSerializer
end

# Create a project
#
# @path [POST] /api/cli/v1/accounts/{account_id}/projects
Expand All @@ -17,7 +23,7 @@ class UffizziCore::Api::Cli::V1::Accounts::ProjectsController < UffizziCore::Api

def create
project_form = UffizziCore::Api::Cli::V1::Project::CreateForm.new(project_params)
project_form.account = current_user.accounts.find(params[:account_id])
project_form.account = resource_account
UffizziCore::ProjectService.add_users_to_project!(project_form, project_form.account) if project_form.save

respond_with project_form
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

# @resource Project

class UffizziCore::Api::Cli::V1::AccountsController < UffizziCore::Api::Cli::V1::ApplicationController
before_action :authorize_uffizzi_core_api_cli_v1_accounts

# Get accounts of current user
#
# @path [GET] /api/cli/v1/accounts
#
# @response [object<accounts: Array<object<id: integer, name: string>> >] 200 OK
# @response 401 Not authorized
def index
accounts = current_user.accounts.order(name: :desc)

respond_with accounts
end

# Get account by name
#
# @path [GET] /api/cli/v1/accounts/{name}
#
# @response [object<account: <object<id: integer, name: string, projects: Array<object<id: integer, slug: string>>>> >] 200 OK
# @response 401 Not authorized
def show
respond_with resource_account
end

private

def policy_context
account = resource_account || current_user.default_account

UffizziCore::AccountContext.new(current_user, user_access_module, account, params)
end

def resource_account
@resource_account ||= if params[:name]
current_user.accounts.find_by!(name: params[:name])
else
current_user.default_account
end
end
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# frozen_string_literal: true

class UffizziCore::Api::Cli::V1::Accounts::ProjectsPolicy < UffizziCore::ApplicationPolicy
def index?
context.user_access_module.any_access_to_account?(context.user, context.account)
end

def create?
context.user_access_module.admin_or_developer_access_to_account?(context.user, context.account)
end
Expand Down
11 changes: 11 additions & 0 deletions core/app/policies/uffizzi_core/api/cli/v1/accounts_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class UffizziCore::Api::Cli::V1::AccountsPolicy < UffizziCore::ApplicationPolicy
def index?
context.user.present?
end

def show?
context.user_access_module.any_access_to_account?(context.user, context.account)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class UffizziCore::Api::Cli::V1::AccountSerializer < UffizziCore::BaseSerializer
type :account

has_many :projects

attributes :id, :name
end
6 changes: 4 additions & 2 deletions core/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
resource :session, only: ['create']
end

resources :accounts, only: [] do
resources :accounts, only: ['show'], param: :name

resources :accounts, only: ['index'] do
scope module: :accounts do
resources :projects, only: ['create']
resources :projects, only: ['index', 'create']
resources :credentials, only: ['index', 'create', 'update', 'destroy'], param: :type do
member do
get :check_credential
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@
class UffizziCore::Api::Cli::V1::Accounts::ProjectsControllerTest < ActionController::TestCase
setup do
@user = create(:user, :with_personal_account)
@account = @user.personal_account
sign_in @user
end

test '#index' do
create(:project, :with_members, account: @account, members: [@user])

get :index, params: { account_id: @account.id }, format: :json

assert_response(:success)
end

test '#create' do
attributes = attributes_for(:project)

Expand All @@ -17,9 +26,9 @@ class UffizziCore::Api::Cli::V1::Accounts::ProjectsControllerTest < ActionContro
}

assert_difference differences do
post :create, params: { account_id: @user.personal_account.id, project: attributes }, format: :json
post :create, params: { account_id: @account.id, project: attributes }, format: :json
end

assert_response :success
assert_response(:success)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require 'test_helper'

class UffizziCore::Api::Cli::V1::AccountsControllerTest < ActionController::TestCase
setup do
@user = create(:user, :with_personal_account)
sign_in(@user)
end

test '#index' do
get :index, format: :json

assert_response(:success)
end

test '#show' do
get :show, params: { name: 'wrong' }, format: :json

assert_response(:not_found)
end
end
22 changes: 17 additions & 5 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@
creation_source: UffizziCore::User.creation_source.system,
)

account = UffizziCore::Account.create!(
personal_account = UffizziCore::Account.create!(
owner: user,
name: 'default',
name: 'personal',
state: UffizziCore::Account::STATE_ACTIVE,
kind: UffizziCore::Account.kind.personal,
)

user.memberships.create!(account: account, role: UffizziCore::Membership.role.admin)
organizational_account = UffizziCore::Account.create!(
owner: user,
name: 'organizational',
state: UffizziCore::Account::STATE_ACTIVE,
kind: UffizziCore::Account.kind.organizational,
)

user.memberships.create!(account: personal_account, role: UffizziCore::Membership.role.admin)
user.memberships.create!(account: organizational_account, role: UffizziCore::Membership.role.admin)

personal_project = personal_account.projects.create!(name: 'default', slug: 'default', state: UffizziCore::Project::STATE_ACTIVE)
personal_project.user_projects.create!(user: user, role: UffizziCore::UserProject.role.admin)

project = account.projects.create!(name: 'default', slug: 'default', state: UffizziCore::Project::STATE_ACTIVE)
project.user_projects.create!(user: user, role: UffizziCore::UserProject.role.admin)
organizational_project = organizational_account.projects.create!(name: 'uffizzi', slug: 'uffizzi',
state: UffizziCore::Project::STATE_ACTIVE)
organizational_project.user_projects.create!(user: user, role: UffizziCore::UserProject.role.admin)