Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class Api::V1::Shopkeeper::Account::PasswordsController < Api::V1::Shopkeeper::BaseController
skip_after_action :verify_authorized

def update
authorize :password

if current_shopkeeper.update_with_password(password_params)
render json: {status: 200}, status: :ok
else
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
class Api::V1::Shopkeeper::Accounts::AccountsInvitationsController < Api::V1::Shopkeeper::BaseController
before_action :set_account
before_action :require_account_admin, except: %i[index show]
before_action :set_accounts_invitation, only: %i[show update destroy resend]
skip_after_action :verify_authorized

def index
authorize AccountsInvitation

@accounts_invitations = @account.accounts_invitations.order(name: :asc)
render json: AccountsInvitationSerializer.new(@accounts_invitations).serializable_hash
end

def show
authorize @accounts_invitation

options = {}
options[:include] = [:account, :invited_by]
render json: AccountsInvitationSerializer.new(@accounts_invitation, options).serializable_hash
end

def create
authorize AccountsInvitation

accounts_invitation = @account.accounts_invitations.build(invitation_params_create)

if accounts_invitation.save_and_send_invite
Expand All @@ -26,6 +30,8 @@ def create
end

def update
authorize @accounts_invitation

if @accounts_invitation.update(invitation_params_update)
render json: AccountsInvitationSerializer.new(@accounts_invitation).serializable_hash
else
Expand All @@ -34,17 +40,25 @@ def update
end

def destroy
authorize @accounts_invitation

@accounts_invitation.destroy
render json: {status: 200}, status: :ok
end

def resend
authorize @accounts_invitation

@accounts_invitation.resend_invite
render json: {status: 200}, status: :ok
end

private

def pundit_user
@account.accounts_shopkeepers.find_by!(shopkeeper: current_shopkeeper)
end

def set_account
@account = current_shopkeeper.accounts.find(params[:account_id])
end
Expand All @@ -65,11 +79,4 @@ def invitation_params_update
.require(:accounts_invitation)
.permit(:name, AccountsShopkeeper::ROLES)
end

def require_account_admin
accounts_shopkeeper = @account.accounts_shopkeepers.find_by(shopkeeper: current_shopkeeper)
return if accounts_shopkeeper&.admin?

render json: {code: 401, error_message: I18n.t("api.shopkeeper.accounts.admin_required")}, status: :unauthorized
end
end
34 changes: 18 additions & 16 deletions app/controllers/api/v1/shopkeeper/accounts_controller.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
class Api::V1::Shopkeeper::AccountsController < Api::V1::Shopkeeper::BaseController
before_action :set_account, only: %i[show update destroy]
before_action :require_account_admin, only: %i[update]
before_action :require_account_owner, only: %i[destroy]
before_action :prevent_personal_account_deletion, only: %i[destroy]
skip_after_action :verify_authorized

# GET /accounts
def index
authorize Account

accounts = current_shopkeeper.accounts.sorted
options = {
params: {current_shopkeeper: current_shopkeeper}
Expand All @@ -24,6 +23,8 @@ def index

# GET /accounts/1
def show
authorize @account

options = {
include: [:accounts_shopkeepers, :accounts_invitations],
params: {current_shopkeeper: current_shopkeeper}
Expand All @@ -33,6 +34,8 @@ def show

# POST /accounts
def create
authorize Account

account = Account.new(account_params.merge(owner: current_shopkeeper))
account.accounts_shopkeepers.new(shopkeeper: current_shopkeeper, admin: true)

Expand All @@ -49,6 +52,8 @@ def create

# PATCH/PUT /accounts/1
def update
authorize @account

if @account.update(account_params)
options = {
params: {current_shopkeeper: current_shopkeeper}
Expand All @@ -61,6 +66,8 @@ def update

# DELETE /accounts/1
def destroy
authorize @account

ActsAsTenant.without_tenant do
@account.destroy
end
Expand All @@ -80,22 +87,17 @@ def account_params
params.require(:account).permit(:name)
end

def pundit_user
if @account
@account.accounts_shopkeepers.find_by!(shopkeeper: current_shopkeeper)
else
super
end
end

def prevent_personal_account_deletion
return unless @account.personal?

render json: {code: 422, error_message: I18n.t("api.shopkeeper.accounts.personal.cannot_delete")}, status: :unprocessable_entity
end

def require_account_admin
accounts_shopkeeper = @account.accounts_shopkeepers.find_by(shopkeeper: current_shopkeeper)
return if accounts_shopkeeper&.admin?

render json: {code: 401, error_message: I18n.t("api.shopkeeper.accounts.admin_required")}, status: :unauthorized
end

def require_account_owner
return if @account.owner?(current_shopkeeper)

render json: {code: 401, error_message: I18n.t("api.shopkeeper.accounts.owner_required")}, status: :unauthorized
end
end
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
class Api::V1::Shopkeeper::AccountsInvitationsController < Api::V1::Shopkeeper::BaseController
before_action :set_accounts_invitation
skip_after_action :verify_authorized

def show
authorize @accounts_invitation, :show_by_token?

if @accounts_invitation.expired?
render json: {code: 410, error_message: I18n.t("api.shopkeeper.accounts_invitations.expired")}, status: :gone
return
Expand All @@ -14,6 +15,8 @@ def show
end

def update
authorize @accounts_invitation, :accept?

if @accounts_invitation.expired?
render json: {code: 410, error_message: I18n.t("api.shopkeeper.accounts_invitations.expired")}, status: :gone
return
Expand All @@ -28,6 +31,8 @@ def update
end

def destroy
authorize @accounts_invitation, :reject?

@accounts_invitation.reject!
render json: {status: 200}, status: :ok
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ class Api::V1::Shopkeeper::AccountsShopkeepersController < Api::V1::Shopkeeper::
before_action :set_account
before_action :require_non_personal_account!, only: %i[show update destroy]
before_action :set_accounts_shopkeeper, only: %i[show update destroy]
before_action :require_account_admin, except: %i[index show]
before_action :safeguard_account_owner_deletion!, only: %i[destroy]
skip_after_action :verify_authorized

def index
authorize AccountsShopkeeper

if @account.personal?
render json: AccountsShopkeeperSerializer.new([]).serializable_hash and return
end
Expand All @@ -19,13 +19,17 @@ def index
end

def show
authorize @accounts_shopkeeper

options = {}
options[:include] = [:account, :shopkeeper]

render json: AccountsShopkeeperSerializer.new(@accounts_shopkeeper, options).serializable_hash
end

def update
authorize @accounts_shopkeeper

if @accounts_shopkeeper.update(accounts_shopkeeper_params)
options = {}
options[:include] = [:account, :shopkeeper]
Expand All @@ -37,12 +41,18 @@ def update
end

def destroy
authorize @accounts_shopkeeper

@accounts_shopkeeper.destroy
render json: {status: 200}, status: :ok
end

private

def pundit_user
@account.accounts_shopkeepers.find_by!(shopkeeper: current_shopkeeper)
end

def set_account
@account = current_shopkeeper.accounts.find(params[:account_id])
end
Expand All @@ -68,11 +78,4 @@ def safeguard_account_owner_deletion!

render json: {code: 401, error_message: I18n.t("unauthorized")}, status: :unauthorized
end

def require_account_admin
accounts_shopkeeper = @account.accounts_shopkeepers.find_by(shopkeeper: current_shopkeeper)
return if accounts_shopkeeper&.admin?

render json: {code: 401, error_message: I18n.t("api.shopkeeper.accounts.admin_required")}, status: :unauthorized
end
end
5 changes: 4 additions & 1 deletion app/controllers/api/v1/shopkeeper/me_controller.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
class Api::V1::Shopkeeper::MeController < Api::V1::Shopkeeper::BaseController
before_action :set_shopkeeper, only: %i[update_confirmed_privacy_version update_confirmed_terms_version]
skip_after_action :verify_authorized

def update_confirmed_privacy_version
authorize :me

@shopkeeper.confirmed_privacy_version = PrivacyVersion.current_version
@shopkeeper.save!(validate: false)
render json: {status: 200}, status: :ok
end

def update_confirmed_terms_version
authorize :me

@shopkeeper.confirmed_terms_version = TermsVersion.current_version
@shopkeeper.save!(validate: false)
render json: {status: 200}, status: :ok
Expand Down
23 changes: 23 additions & 0 deletions app/policies/api/shopkeeper/account_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Api::Shopkeeper::AccountPolicy < Api::Shopkeeper::BasePolicy
include Api::Shopkeeper::Concerns::Authorization

def index?
true
end

def show?
true
end

def create?
true
end

def update?
admin?
end

def destroy?
owner?
end
end
40 changes: 40 additions & 0 deletions app/policies/api/shopkeeper/accounts_invitation_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Api::Shopkeeper::AccountsInvitationPolicy < Api::Shopkeeper::BasePolicy
include Api::Shopkeeper::Concerns::Authorization

def index?
true
end

def show?
true
end

def create?
admin?
end

def update?
admin?
end

def destroy?
admin?
end

def resend?
admin?
end

# Token-based actions (any authenticated shopkeeper with the token)
def show_by_token?
true
end

def accept?
true
end

def reject?
true
end
end
19 changes: 19 additions & 0 deletions app/policies/api/shopkeeper/accounts_shopkeeper_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class Api::Shopkeeper::AccountsShopkeeperPolicy < Api::Shopkeeper::BasePolicy
include Api::Shopkeeper::Concerns::Authorization

def index?
true
end

def show?
true
end

def update?
admin?
end

def destroy?
admin?
end
end
9 changes: 9 additions & 0 deletions app/policies/api/shopkeeper/me_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Api::Shopkeeper::MePolicy < Api::Shopkeeper::BasePolicy
def update_confirmed_privacy_version?
true
end

def update_confirmed_terms_version?
true
end
end
5 changes: 5 additions & 0 deletions app/policies/api/shopkeeper/password_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Api::Shopkeeper::PasswordPolicy < Api::Shopkeeper::BasePolicy
def update?
true
end
end
2 changes: 1 addition & 1 deletion render.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ services:
name: nativeapptemplateapi
plan: standard
previews:
plan: starter
plan: standard
env: ruby
region: singapore # the region must be consistent across all services for the internal keys to be read
buildCommand: "./bin/render-build.sh"
Expand Down
Loading