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

Registry 992 #1042

Merged
merged 1 commit into from
Dec 10, 2018
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
16 changes: 16 additions & 0 deletions app/controllers/api/v1/registrant/contacts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ def update
contact.email = params[:email] if params[:email].present?
contact.phone = params[:phone] if params[:phone].present?

# Needed to support passing empty array, which otherwise gets parsed to nil
# https://github.com/rails/rails/pull/13157
reparsed_request_json = ActiveSupport::JSON.decode(request.body.string)
.with_indifferent_access
disclosed_attributes = reparsed_request_json[:disclosed_attributes]

if disclosed_attributes
if contact.org?
error_msg = "Legal person's data cannot be concealed. Please remove this parameter."
render json: { errors: [{ disclosed_attributes: [error_msg] }] }, status: :bad_request
return
end

contact.disclosed_attributes = disclosed_attributes
end

if Setting.address_processing && params[:address]
address = Contact::Address.new(params[:address][:street],
params[:address][:zip],
Expand Down
26 changes: 26 additions & 0 deletions app/models/concerns/contact/disclosable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Concerns
module Contact
module Disclosable
extend ActiveSupport::Concern

class_methods do
attr_accessor :disclosable_attributes
end

included do
self.disclosable_attributes = %w[name email]
validate :validate_disclosed_attributes
end

private

def validate_disclosed_attributes
return if disclosed_attributes.empty?

has_undisclosable_attributes = (disclosed_attributes - self.class.disclosable_attributes)
.any?
errors.add(:disclosed_attributes, :invalid) if has_undisclosable_attributes
end
end
end
end
1 change: 1 addition & 0 deletions app/models/contact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class Contact < ActiveRecord::Base
include UserEvents
include Concerns::Contact::Transferable
include Concerns::Contact::Identical
include Concerns::Contact::Disclosable

belongs_to :original, class_name: self.name
belongs_to :registrar, required: true
Expand Down
29 changes: 17 additions & 12 deletions app/models/whois_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,18 @@ def generate_json

h[:email] = registrant.email
h[:registrant_changed] = registrant.updated_at.try(:to_s, :iso8601)
h[:registrant_disclosed_attributes] = registrant.disclosed_attributes

h[:admin_contacts] = []
domain.admin_contacts.each do |ac|
h[:admin_contacts] << {
name: ac.name,
email: ac.email,
changed: ac.updated_at.try(:to_s, :iso8601)
}

domain.admin_contacts.each do |contact|
h[:admin_contacts] << contact_json_hash(contact)
end

h[:tech_contacts] = []
domain.tech_contacts.each do |tc|
h[:tech_contacts] << {
name: tc.name,
email: tc.email,
changed: tc.updated_at.try(:to_s, :iso8601)
}

domain.tech_contacts.each do |contact|
h[:tech_contacts] << contact_json_hash(contact)
end

# update registar triggers when adding new attributes
Expand Down Expand Up @@ -109,4 +105,13 @@ def destroy_whois_record
def disclaimer_text
Setting.registry_whois_disclaimer
end

def contact_json_hash(contact)
{
name: contact.name,
email: contact.email,
changed: contact.updated_at.try(:to_s, :iso8601),
disclosed_attributes: contact.disclosed_attributes,
}
end
end
4 changes: 2 additions & 2 deletions app/views/admin/registrars/form/_billing.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<div class="form-group">
<% if f.object.new_record? %>
<div class="col-md-offset-4 col-md-8">
<%= t '.no_reference_no_hint' %>
<%= t '.no_reference_number_hint' %>
</div>
<% else %>
<div class="col-md-4 control-label">
Expand All @@ -60,7 +60,7 @@

<div class="col-md-7">
<%= f.text_field :reference_no, disabled: true,
title: t('.disabled_reference_no_hint'),
title: t('.disabled_reference_number_hint'),
class: 'form-control' %>
</div>
<% end %>
Expand Down
4 changes: 2 additions & 2 deletions config/locales/admin/registrars.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ en:

billing:
header: Billing
no_reference_no_hint: Reference number will be generated automatically
disabled_reference_no_hint: Reference number cannot be changed
no_reference_number_hint: Reference number will be generated automatically
disabled_reference_number_hint: Reference number cannot be changed

preferences:
header: Preferences
Expand Down
2 changes: 2 additions & 0 deletions config/locales/contacts.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ en:
not_uniq: 'not uniq'
country_code:
invalid: Country code is not valid, should be in ISO_3166-1 alpha 2 format (%{value})
disclosed_attributes:
invalid: contain unsupported attribute(s)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddContactsDisclosedAttributes < ActiveRecord::Migration
def change
add_column :contacts, :disclosed_attributes, :string, array: true, default: [], null: false
end
end
5 changes: 4 additions & 1 deletion db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,8 @@ CREATE TABLE public.contacts (
ident_updated_at timestamp without time zone,
upid integer,
up_date timestamp without time zone,
uuid uuid DEFAULT public.gen_random_uuid() NOT NULL
uuid uuid DEFAULT public.gen_random_uuid() NOT NULL,
disclosed_attributes character varying[] DEFAULT '{}'::character varying[] NOT NULL
);


Expand Down Expand Up @@ -4861,3 +4862,5 @@ INSERT INTO schema_migrations (version) VALUES ('20181001090536');

INSERT INTO schema_migrations (version) VALUES ('20181002090319');

INSERT INTO schema_migrations (version) VALUES ('20181108154921');

9 changes: 6 additions & 3 deletions doc/registrant-api/v1/contact.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,14 @@ Content-Type: application/json
"auth_info": "password",
"statuses": [
"ok"
]
],
"disclosed_attributes": ["name"]
}
```

## PATCH /api/v1/registrant/contacts/$UUID

Update contact details for a contact.
Update contact.

#### Parameters

Expand All @@ -112,6 +113,7 @@ Update contact details for a contact.
| address[city] | false | String | | New city name |
| address[state] | false | String | | New state name |
| address[country_code] | false | String | | New country code in 2 letter format (ISO 3166-1 alpha-2) |
| disclosed_attributes | false | Array | | Possible values: "name", "email"


#### Request
Expand All @@ -132,7 +134,8 @@ Content-type: application/json
"city":"New City",
"state":"New state",
"country_code":"LV"
}
},
"disclosed_attributes": ["name"]
}

```
Expand Down
3 changes: 2 additions & 1 deletion lib/serializers/registrant_api/contact.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ def to_json
country_code: contact.country_code,
},
auth_info: contact.auth_info,
statuses: contact.statuses
statuses: contact.statuses,
disclosed_attributes: contact.disclosed_attributes,
}
end
end
Expand Down
49 changes: 48 additions & 1 deletion test/integration/api/v1/registrant/contacts/update_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,51 @@ def test_address_cannot_be_updated_when_disabled
symbolize_names: true)
end

def test_disclose_private_persons_data
@contact.update!(ident_type: Contact::PRIV,
disclosed_attributes: %w[])

patch api_v1_registrant_contact_path(@contact.uuid), { disclosed_attributes: %w[name] }.to_json,
'HTTP_AUTHORIZATION' => auth_token,
'Accept' => Mime::JSON,
'Content-Type' => Mime::JSON.to_s
@contact.reload

assert_response :ok
assert_equal %w[name], @contact.disclosed_attributes
end

def test_conceal_private_persons_data
@contact.update!(ident_type: Contact::PRIV, disclosed_attributes: %w[name])

patch api_v1_registrant_contact_path(@contact.uuid), { disclosed_attributes: [] }.to_json,
{ 'HTTP_AUTHORIZATION' => auth_token,
'Accept' => Mime::JSON,
'Content-Type' => Mime::JSON.to_s }

@contact.reload

assert_response :ok
assert_empty @contact.disclosed_attributes
end

def test_legal_persons_data_cannot_be_concealed
@contact.update!(ident_type: Contact::ORG,
disclosed_attributes: %w[])

assert_no_changes -> { @contact.disclosed_attributes } do
patch api_v1_registrant_contact_path(@contact.uuid), { disclosed_attributes: %w[name] }.to_json,
'HTTP_AUTHORIZATION' => auth_token,
'Accept' => Mime::JSON,
'Content-Type' => Mime::JSON.to_s
@contact.reload
end
assert_response :bad_request
error_msg = "Legal person's data cannot be concealed. Please remove this parameter."
assert_equal ({ errors: [{ disclosed_attributes: [error_msg] }] }),
JSON.parse(response.body, symbolize_names: true)
end

def test_return_contact_details
patch api_v1_registrant_contact_path(@contact.uuid), { name: 'new name' }.to_json,
'HTTP_AUTHORIZATION' => auth_token,
Expand All @@ -153,7 +198,9 @@ def test_return_contact_details
country_code: @contact.country_code,
},
auth_info: @contact.auth_info,
statuses: @contact.statuses }), JSON.parse(response.body, symbolize_names: true)
statuses: @contact.statuses,
disclosed_attributes: @contact.disclosed_attributes }),
JSON.parse(response.body, symbolize_names: true)
end

def test_errors
Expand Down
39 changes: 39 additions & 0 deletions test/models/contact/disclosable_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'test_helper'

class ContactDisclosableTest < ActiveSupport::TestCase
setup do
@contact = contacts(:john)
@original_disclosable_attributes = Contact.disclosable_attributes
end

teardown do
Contact.disclosable_attributes = @original_disclosable_attributes
end

def test_no_disclosed_attributes_by_default
assert_empty Contact.new.disclosed_attributes
end

def test_disclosable_attributes
assert_equal %w[name email], Contact.disclosable_attributes
end

def test_valid_without_disclosed_attributes
@contact.disclosed_attributes = []
assert @contact.valid?
end

def test_invalid_when_attribute_is_not_disclosable
Contact.disclosable_attributes = %w[some disclosable]
@contact.disclosed_attributes = %w[some undisclosable]

assert @contact.invalid?
assert_includes @contact.errors.get(:disclosed_attributes), 'contain unsupported attribute(s)'
end

def test_valid_when_attribute_is_disclosable
Contact.disclosable_attributes = %w[some disclosable]
@contact.disclosed_attributes = %w[disclosable]
assert @contact.valid?
end
end
4 changes: 2 additions & 2 deletions test/models/contact_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class ContactTest < ActiveSupport::TestCase
end

def test_valid_fixture
assert @contact.valid?
assert @contact.valid?, proc { @contact.errors.full_messages }
end

def test_invalid_without_email
Expand Down Expand Up @@ -48,4 +48,4 @@ def test_address
assert_equal 'EE', @contact.country_code
assert_equal address, @contact.address
end
end
end
18 changes: 12 additions & 6 deletions test/models/whois_record_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ def test_whois_record_has_no_disclaimer_if_Setting_is_blank
end

def test_generates_json_with_registrant
registrant = contacts(:john).becomes(Registrant)
registrant.update!(name: 'John', kind: 'priv', email: '[email protected]',
updated_at: Time.zone.parse('2010-07-05'))
contact = contacts(:john)
contact.update!(name: 'John', kind: 'priv', email: '[email protected]',
updated_at: Time.zone.parse('2010-07-05'),
disclosed_attributes: %w[name])

domain = domains(:shop)
domain.update!(registrant: registrant)
domain.update!(registrant: contact.becomes(Registrant))

whois_record = whois_records(:shop)
whois_record.update!(json: {})
Expand All @@ -54,12 +55,14 @@ def test_generates_json_with_registrant
assert_equal 'priv', generated_json[:registrant_kind]
assert_equal '[email protected]', generated_json[:email]
assert_equal '2010-07-05T00:00:00+03:00', generated_json[:registrant_changed]
assert_equal %w[name], generated_json[:registrant_disclosed_attributes]
end

def test_generates_json_with_admin_contacts
contact = contacts(:john)
contact.update!(name: 'John', email: '[email protected]',
updated_at: Time.zone.parse('2010-07-05'))
updated_at: Time.zone.parse('2010-07-05'),
disclosed_attributes: %w[name])

domain = domains(:shop)
domain.admin_contacts = [contact]
Expand All @@ -71,12 +74,14 @@ def test_generates_json_with_admin_contacts
assert_equal 'John', admin_contact_json[:name]
assert_equal '[email protected]', admin_contact_json[:email]
assert_equal '2010-07-05T00:00:00+03:00', admin_contact_json[:changed]
assert_equal %w[name], admin_contact_json[:disclosed_attributes]
end

def test_generates_json_with_tech_contacts
contact = contacts(:john)
contact.update!(name: 'John', email: '[email protected]',
updated_at: Time.zone.parse('2010-07-05'))
updated_at: Time.zone.parse('2010-07-05'),
disclosed_attributes: %w[name])

domain = domains(:shop)
domain.tech_contacts = [contact]
Expand All @@ -88,5 +93,6 @@ def test_generates_json_with_tech_contacts
assert_equal 'John', tech_contact_json[:name]
assert_equal '[email protected]', tech_contact_json[:email]
assert_equal '2010-07-05T00:00:00+03:00', tech_contact_json[:changed]
assert_equal %w[name], tech_contact_json[:disclosed_attributes]
end
end