diff --git a/app/controllers/repp/v1/accounts_controller.rb b/app/controllers/repp/v1/accounts_controller.rb index a405646ca..e14f7ecdb 100644 --- a/app/controllers/repp/v1/accounts_controller.rb +++ b/app/controllers/repp/v1/accounts_controller.rb @@ -34,8 +34,12 @@ module Repp iban: registrar.iban, iban_max_length: Iban.max_length, linked_users: serialized_users(current_user.linked_users), + api_users: serialized_users(current_user.api_users), + white_ips: serialized_ips(registrar.white_ips), balance_auto_reload: type, - min_deposit: Setting.minimum_deposit } } + min_deposit: Setting.minimum_deposit }, + roles: ApiUser::ROLES, + interfaces: WhiteIp::INTERFACES } render_success(data: resp) end @@ -148,7 +152,8 @@ module Repp arr = [] users.each do |u| arr << { id: u.id, username: u.username, - role: u.roles.first, registrar_name: u.registrar.name } + role: u.roles.first, registrar_name: u.registrar.name, + active: u.active } end arr @@ -165,6 +170,10 @@ module Repp arr end + + def serialized_ips(ips) + ips.as_json(only: %i[id ipv4 ipv6 interfaces]) + end end end end diff --git a/app/controllers/repp/v1/api_users_controller.rb b/app/controllers/repp/v1/api_users_controller.rb new file mode 100644 index 000000000..56e294be0 --- /dev/null +++ b/app/controllers/repp/v1/api_users_controller.rb @@ -0,0 +1,73 @@ +require 'serializers/repp/api_user' +module Repp + module V1 + class ApiUsersController < BaseController + load_and_authorize_resource + + THROTTLED_ACTIONS = %i[index show create update destroy].freeze + include Shunter::Integration::Throttle + + api :GET, '/repp/v1/api_users' + desc 'Get all api users' + def index + users = current_user.registrar.api_users + + render_success(data: { users: serialized_users(users), + count: users.count }) + end + + api :GET, '/repp/v1/api_users/:id' + desc 'Get a specific api user' + def show + serializer = Serializers::Repp::ApiUser.new(@api_user) + render_success(data: { user: serializer.to_json, roles: ApiUser::ROLES }) + end + + api :POST, '/repp/v1/api_users' + desc 'Create a new api user' + def create + @api_user = current_user.registrar.api_users.build(api_user_params) + @api_user.active = api_user_params[:active] + unless @api_user.save + handle_non_epp_errors(@api_user) + return + end + + render_success(data: { api_user: { id: @api_user.id } }) + end + + api :PUT, '/repp/v1/api_users/:id' + desc 'Update api user' + def update + unless @api_user.update(api_user_params) + handle_non_epp_errors(@api_user) + return + end + + render_success(data: { api_user: { id: @api_user.id } }) + end + + api :DELETE, '/repp/v1/api_users/:id' + desc 'Delete a specific api user' + def destroy + unless @api_user.destroy + handle_non_epp_errors(@api_user) + return + end + + render_success + end + + private + + def api_user_params + params.require(:api_user).permit(:id, :username, :plain_text_password, :active, + :identity_code, { roles: [] }) + end + + def serialized_users(users) + users.map { |i| Serializers::Repp::ApiUser.new(i).to_json } + end + end + end +end diff --git a/app/controllers/repp/v1/white_ips_controller.rb b/app/controllers/repp/v1/white_ips_controller.rb new file mode 100644 index 000000000..6ece2aea9 --- /dev/null +++ b/app/controllers/repp/v1/white_ips_controller.rb @@ -0,0 +1,59 @@ +module Repp + module V1 + class WhiteIpsController < BaseController + load_and_authorize_resource + + THROTTLED_ACTIONS = %i[index create update destroy].freeze + include Shunter::Integration::Throttle + + api :GET, '/repp/v1/white_ips' + desc 'Get all whitelisted ips' + def index + ips = current_user.registrar.white_ips + + render_success(data: { ips: ips.as_json(except: %i[creator_str updator_str]), + count: ips.count }) + end + + api :POST, '/repp/v1/white_ips' + desc 'Add new whitelisted IP' + def create + @white_ip = current_user.registrar.white_ips.build(white_ip_params) + unless @white_ip.save + handle_non_epp_errors(@white_ip) + return + end + + render_success(data: { ip: { id: @white_ip.id } }) + end + + api :PUT, '/repp/v1/white_ips/:id' + desc 'Update whitelisted ip address' + def update + unless @white_ip.update(white_ip_params) + handle_non_epp_errors(@white_ip) + return + end + + render_success(data: { ip: { id: @white_ip.id } }) + end + + api :DELETE, '/repp/v1/white_ips/:id' + desc 'Delete a specific whitelisted ip address' + def destroy + unless @white_ip.destroy + handle_non_epp_errors(@white_ip) + return + end + + render_success + end + + private + + def white_ip_params + params.require(:white_ip).permit(:ipv4, :ipv6, interfaces: []) + end + end + end +end diff --git a/app/models/ability.rb b/app/models/ability.rb index d90283262..d7b2496f2 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -28,6 +28,8 @@ class Ability def super # Registrar/api_user dynamic role epp billing + can :manage, ApiUser + can :manage, WhiteIp end def epp # Registrar/api_user dynamic role diff --git a/app/models/api_user.rb b/app/models/api_user.rb index 73e0f6c4e..d6572999e 100644 --- a/app/models/api_user.rb +++ b/app/models/api_user.rb @@ -24,6 +24,7 @@ class ApiUser < User validates :username, :plain_text_password, :registrar, :roles, presence: true validates :plain_text_password, length: { minimum: min_password_length } validates :username, uniqueness: true + validates :identity_code, uniqueness: { scope: :registrar_id }, if: -> { identity_code.present? } delegate :code, :name, to: :registrar, prefix: true delegate :legaldoc_mandatory?, to: :registrar @@ -36,6 +37,8 @@ class ApiUser < User ROLES = %w[super epp billing].freeze # should not match to admin roles + scope :non_super, -> { where.not('roles @> ARRAY[?]::varchar[]', ['super']) } + def ability @ability ||= Ability.new(self) end @@ -81,12 +84,16 @@ class ApiUser < User end def linked_users - self.class.where(identity_code: identity_code) + self.class.where(identity_code: identity_code, active: true) .where("identity_code IS NOT NULL AND identity_code != ''") .where.not(id: id) .includes(:registrar) end + def api_users + self.class.where(registrar_id: registrar_id) + end + def linked_with?(another_api_user) another_api_user.identity_code == identity_code end @@ -109,6 +116,14 @@ class ApiUser < User 'Accreditation Expire Date', 'Created', 'Updated'] end + def self.ransackable_associations(*) + authorizable_ransackable_associations + end + + def self.ransackable_attributes(*) + authorizable_ransackable_attributes + end + private def machine_readable_certificate(cert) diff --git a/app/models/white_ip.rb b/app/models/white_ip.rb index a90b8cdd2..e57bff8b2 100644 --- a/app/models/white_ip.rb +++ b/app/models/white_ip.rb @@ -77,6 +77,10 @@ class WhiteIp < ApplicationRecord def csv_header %w[IPv4 IPv6 Interfaces Created Updated] end + + def ransackable_attributes(auth_object = nil) + ["created_at", "creator_str", "id", "interfaces", "ipv4", "ipv6", "registrar_id", "updated_at", "updator_str"] + end end def as_csv_row diff --git a/config/routes.rb b/config/routes.rb index 25d73043f..4677f01e1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -108,6 +108,8 @@ Rails.application.routes.draw do get '/market_share_growth_rate', to: 'stats#market_share_growth_rate' end end + resources :api_users, only: %i[index show update create destroy] + resources :white_ips, only: %i[index update create destroy] namespace :registrar do resources :notifications, only: %i[index show update] do collection do diff --git a/lib/serializers/repp/api_user.rb b/lib/serializers/repp/api_user.rb new file mode 100644 index 000000000..c17482d9e --- /dev/null +++ b/lib/serializers/repp/api_user.rb @@ -0,0 +1,38 @@ +module Serializers + module Repp + class ApiUser + attr_reader :user + + def initialize(user) + @user = user + end + + def to_json(obj = user) + json = { + id: obj.id, + name: obj.username, + password: obj.plain_text_password, + identity_code: obj.identity_code, + roles: obj.roles.join(', '), + active: obj.active, + accredited: obj.accredited?, + accreditation_expired: obj.accreditation_expired?, + accreditation_expire_date: obj.accreditation_expire_date, + created_at: obj.created_at, + updated_at: obj.updated_at, + } + json[:certificates] = certificates + json + end + + private + + def certificates + user.certificates.map do |x| + subject = x.csr ? x.parsed_csr.try(:subject) : x.parsed_crt.try(:subject) + { subject: subject.to_s, status: x.status } + end + end + end + end +end diff --git a/lib/serializers/repp/invoice.rb b/lib/serializers/repp/invoice.rb index 686eaac99..ceef7c654 100644 --- a/lib/serializers/repp/invoice.rb +++ b/lib/serializers/repp/invoice.rb @@ -81,6 +81,7 @@ module Serializers total: invoice.total, recipient: invoice.buyer.billing_email, monthly_invoice: invoice.monthly_invoice, + reference_no: invoice.reference_no } end # rubocop:enable Metrics/MethodLength