gitlab_support_readiness 1.0.42 → 1.0.44

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. checksums.yaml +4 -4
  2. data/lib/support_readiness/support_super_form_processor/global_set_collaboration_id.rb +1 -1
  3. data/lib/support_readiness/support_super_form_processor/global_set_org_ase.rb +1 -1
  4. data/lib/support_readiness/support_super_form_processor/global_toggle_escalation.rb +1 -1
  5. data/lib/support_readiness/support_super_form_processor/gratis_support_extension.rb +23 -5
  6. data/lib/support_readiness/support_super_form_processor/gratis_support_former_customer.rb +31 -0
  7. data/lib/support_readiness/support_super_form_processor/gratis_support_migration.rb +31 -0
  8. data/lib/support_readiness/support_super_form_processor/gratis_support_other.rb +31 -0
  9. data/lib/support_readiness/support_super_form_processor/gratis_support_prospect.rb +31 -0
  10. data/lib/support_readiness/support_super_form_processor/gratis_support_upgrade.rb +31 -0
  11. data/lib/support_readiness/support_super_form_processor/namespace_availability.rb +1 -1
  12. data/lib/support_readiness/support_super_form_processor/sa_request_for_support.rb +1 -1
  13. data/lib/support_readiness/support_super_form_processor/usgov_set_collaboration_id.rb +1 -1
  14. data/lib/support_readiness/support_super_form_processor/usgov_set_org_ase.rb +1 -1
  15. data/lib/support_readiness/support_super_form_processor.rb +1 -0
  16. data/lib/support_readiness/ticket_processor/account_blocked.rb +289 -0
  17. data/lib/support_readiness/ticket_processor/email_suppressions.rb +135 -0
  18. data/lib/support_readiness/ticket_processor/link_tagger.rb +102 -0
  19. data/lib/support_readiness/ticket_processor/locked_account.rb +53 -0
  20. data/lib/support_readiness/ticket_processor/namesquatting.rb +223 -0
  21. data/lib/support_readiness/ticket_processor/organization_notes.rb +308 -0
  22. data/lib/support_readiness/ticket_processor/star.rb +32 -0
  23. data/lib/support_readiness/ticket_processor/weighting.rb +121 -0
  24. data/lib/support_readiness/ticket_processor.rb +19 -0
  25. data/lib/support_readiness/zendesk/tickets.rb +3 -1
  26. data/lib/support_readiness.rb +1 -0
  27. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 329d7803aa9435db0939a46d9cc4124bf25c51bb5faed1a6a4d8cd6278fc00a4
4
- data.tar.gz: 4da0de2f1303d5b225f4f91077863059ee482fbd7cbe2274df7bb72a400cdab4
3
+ metadata.gz: c93af42de05070b1bfe7139020369a5e8c171315c83dc66f4c997e172780b715
4
+ data.tar.gz: '069e8c0f67891ebf8f69788728ec4317d3b5545a5b110ddd4331f16df9bf224b'
5
5
  SHA512:
6
- metadata.gz: 11cec2ae870755dee110a441c62bfe2c17c73a70c1ff0368b49e6f0e4beab979cd03d95ab863013673e75e6b0c78b908e9f6885c9d76f9679ae5344425c4bcbe
7
- data.tar.gz: 0e83d7b4973c7b3c288eba1dfc9af1eea6848c8e456b4ee2d94ad576fbbf2cece43f78d67dfe3d609e8efe9cb22a0452183e81c4b2885e6ce9d0eaa611088867
6
+ metadata.gz: 65706e165e107ca8620a1c6867066d18b6bd18811820fa301ad6f09830105a8e59ffb3023b1f4ce9ff79951478942edcb1bddf45ce2fc2fd61d45edf3f33797c
7
+ data.tar.gz: 1d933b6d9642aa08834375d1d67de603bcca29b4b21eb8bf466e94258f87c1248fad0645f2c4710a33ddc131719f88868a6f7a230f49dace0e4285f3d568b250
@@ -23,7 +23,7 @@ module Readiness
23
23
  org_does_not_exist if org.is_a? Hash
24
24
  new_org = Readiness::Zendesk::Organizations.new
25
25
  new_org.id = org.id
26
- new_org.custom_fields = {
26
+ new_org.organization_fields = {
27
27
  "am_project_id" => collaboration_project_id
28
28
  }
29
29
  Readiness::Zendesk::Organizations.update!(@zendesk_client, new_org)
@@ -26,7 +26,7 @@ module Readiness
26
26
  invalid_agent unless agent_valid?
27
27
  new_org = Readiness::Zendesk::Organizations.new
28
28
  new_org.id = org.id
29
- new_org.custom_fields = {
29
+ new_org.organization_fields = {
30
30
  "assigned_se" => agent_info
31
31
  }
32
32
  Readiness::Zendesk::Organizations.update!(@zendesk_client, new_org)
@@ -23,7 +23,7 @@ module Readiness
23
23
  org_does_not_exist if org.is_a? Hash
24
24
  new_org = Readiness::Zendesk::Organizations.new
25
25
  new_org.id = org.id
26
- new_org.custom_fields = {
26
+ new_org.organization_fields = {
27
27
  "org_in_escalated_state" => !org.custom_fields['org_in_escalated_state']
28
28
  }
29
29
  Readiness::Zendesk::Organizations.update!(@zendesk_client, new_org)
@@ -58,10 +58,6 @@ module Readiness
58
58
  @requester ||= Readiness::SupportSuperFormProcessor::Shared.gitlab_user_check(@gitlab_admin_client, requester_email)
59
59
  end
60
60
 
61
- def self.manager
62
- @manager ||= Readiness::GitLab::Users.search_by_username(@gitlab_admin_client, manager_handle).detect { |a| a.username == 'manager_handle' }
63
- end
64
-
65
61
  ##
66
62
  # Sets the global variable requester_email
67
63
  #
@@ -81,10 +77,32 @@ module Readiness
81
77
  end
82
78
 
83
79
  ##
84
- # Sets the global variable manager_handle
80
+ # Sets the global variable manager
81
+ #
82
+ # @author Jason Colyer
83
+ # @since 1.0.44
84
+ def self.manager
85
+ @manager ||= determine_manager
86
+ end
87
+
88
+ ##
89
+ # Sets the global variable customer_email
85
90
  #
86
91
  # @author Jason Colyer
87
92
  # @since 1.0.42
93
+ def self.determine_manager
94
+ user_search = Readiness::GitLab::Users.search_by_email(client, manager_handle)
95
+ found_user = user_search.detect { |u| u.email.downcase == email.downcase }
96
+ return nil if found_user.nil?
97
+
98
+ found_user
99
+ end
100
+
101
+ ##
102
+ # Sets the global variable manager_handle
103
+ #
104
+ # @author Jason Colyer
105
+ # @since 1.0.44
88
106
  def self.manager_handle
89
107
  @manager_handle ||= ENV.fetch('GRATUS_SUPPORT_APPROVING_MANAGER')
90
108
  end
@@ -180,6 +180,37 @@ module Readiness
180
180
  @plan ||= ENV.fetch('GRATIS_SUPPORT_NEW_SUB')
181
181
  end
182
182
 
183
+ ##
184
+ # Sets the global variable manager
185
+ #
186
+ # @author Jason Colyer
187
+ # @since 1.0.44
188
+ def self.manager
189
+ @manager ||= determine_manager
190
+ end
191
+
192
+ ##
193
+ # Sets the global variable customer_email
194
+ #
195
+ # @author Jason Colyer
196
+ # @since 1.0.42
197
+ def self.determine_manager
198
+ user_search = Readiness::GitLab::Users.search_by_email(client, manager_handle)
199
+ found_user = user_search.detect { |u| u.email.downcase == email.downcase }
200
+ return nil if found_user.nil?
201
+
202
+ found_user
203
+ end
204
+
205
+ ##
206
+ # Sets the global variable manager_handle
207
+ #
208
+ # @author Jason Colyer
209
+ # @since 1.0.44
210
+ def self.manager_handle
211
+ @manager_handle ||= ENV.fetch('GRATUS_SUPPORT_APPROVING_MANAGER')
212
+ end
213
+
183
214
  ##
184
215
  # Returns a SOQL query string to get Account info
185
216
  #
@@ -147,6 +147,37 @@ module Readiness
147
147
  @plan ||= ENV.fetch('GRATIS_SUPPORT_NEW_SUB')
148
148
  end
149
149
 
150
+ ##
151
+ # Sets the global variable manager
152
+ #
153
+ # @author Jason Colyer
154
+ # @since 1.0.44
155
+ def self.manager
156
+ @manager ||= determine_manager
157
+ end
158
+
159
+ ##
160
+ # Sets the global variable customer_email
161
+ #
162
+ # @author Jason Colyer
163
+ # @since 1.0.42
164
+ def self.determine_manager
165
+ user_search = Readiness::GitLab::Users.search_by_email(client, manager_handle)
166
+ found_user = user_search.detect { |u| u.email.downcase == email.downcase }
167
+ return nil if found_user.nil?
168
+
169
+ found_user
170
+ end
171
+
172
+ ##
173
+ # Sets the global variable manager_handle
174
+ #
175
+ # @author Jason Colyer
176
+ # @since 1.0.44
177
+ def self.manager_handle
178
+ @manager_handle ||= ENV.fetch('GRATUS_SUPPORT_APPROVING_MANAGER')
179
+ end
180
+
150
181
  ##
151
182
  # Returns a SOQL query string to get Account info
152
183
  #
@@ -131,6 +131,37 @@ module Readiness
131
131
  @slack_link ||= ENV.fetch('GRATIS_SUPPORT_SLACK_URL')
132
132
  end
133
133
 
134
+ ##
135
+ # Sets the global variable manager
136
+ #
137
+ # @author Jason Colyer
138
+ # @since 1.0.44
139
+ def self.manager
140
+ @manager ||= determine_manager
141
+ end
142
+
143
+ ##
144
+ # Sets the global variable customer_email
145
+ #
146
+ # @author Jason Colyer
147
+ # @since 1.0.42
148
+ def self.determine_manager
149
+ user_search = Readiness::GitLab::Users.search_by_email(client, manager_handle)
150
+ found_user = user_search.detect { |u| u.email.downcase == email.downcase }
151
+ return nil if found_user.nil?
152
+
153
+ found_user
154
+ end
155
+
156
+ ##
157
+ # Sets the global variable manager_handle
158
+ #
159
+ # @author Jason Colyer
160
+ # @since 1.0.44
161
+ def self.manager_handle
162
+ @manager_handle ||= ENV.fetch('GRATUS_SUPPORT_APPROVING_MANAGER')
163
+ end
164
+
134
165
  ##
135
166
  # Returns a SOQL query string to get Account info
136
167
  #
@@ -180,6 +180,37 @@ module Readiness
180
180
  @customer_email ||= ENV.fetch('GRATIS_SUPPORT_CUSTOMER_EMAIL')
181
181
  end
182
182
 
183
+ ##
184
+ # Sets the global variable manager
185
+ #
186
+ # @author Jason Colyer
187
+ # @since 1.0.44
188
+ def self.manager
189
+ @manager ||= determine_manager
190
+ end
191
+
192
+ ##
193
+ # Sets the global variable customer_email
194
+ #
195
+ # @author Jason Colyer
196
+ # @since 1.0.42
197
+ def self.determine_manager
198
+ user_search = Readiness::GitLab::Users.search_by_email(client, manager_handle)
199
+ found_user = user_search.detect { |u| u.email.downcase == email.downcase }
200
+ return nil if found_user.nil?
201
+
202
+ found_user
203
+ end
204
+
205
+ ##
206
+ # Sets the global variable manager_handle
207
+ #
208
+ # @author Jason Colyer
209
+ # @since 1.0.44
210
+ def self.manager_handle
211
+ @manager_handle ||= ENV.fetch('GRATUS_SUPPORT_APPROVING_MANAGER')
212
+ end
213
+
183
214
  ##
184
215
  # Returns a SOQL query string to get Account info
185
216
  #
@@ -189,6 +189,37 @@ module Readiness
189
189
  @plan ||= ENV.fetch('GRATIS_SUPPORT_NEW_SUB')
190
190
  end
191
191
 
192
+ ##
193
+ # Sets the global variable manager
194
+ #
195
+ # @author Jason Colyer
196
+ # @since 1.0.44
197
+ def self.manager
198
+ @manager ||= determine_manager
199
+ end
200
+
201
+ ##
202
+ # Sets the global variable customer_email
203
+ #
204
+ # @author Jason Colyer
205
+ # @since 1.0.42
206
+ def self.determine_manager
207
+ user_search = Readiness::GitLab::Users.search_by_email(client, manager_handle)
208
+ found_user = user_search.detect { |u| u.email.downcase == email.downcase }
209
+ return nil if found_user.nil?
210
+
211
+ found_user
212
+ end
213
+
214
+ ##
215
+ # Sets the global variable manager_handle
216
+ #
217
+ # @author Jason Colyer
218
+ # @since 1.0.44
219
+ def self.manager_handle
220
+ @manager_handle ||= ENV.fetch('GRATUS_SUPPORT_APPROVING_MANAGER')
221
+ end
222
+
192
223
  ##
193
224
  # Returns a SOQL query string to get Account info
194
225
  #
@@ -57,7 +57,7 @@ module Readiness
57
57
  def self.group_checks
58
58
  group = Readiness::GitLab::Groups.new
59
59
  group.id = namespace.id
60
- projects = Readiness::GitLab::Groups.projects(client, group, ["archived=false", "include_subgroups=true"])
60
+ projects = Readiness::GitLab::Groups.projects(@gitlab_admin_client, group, ["archived=false", "include_subgroups=true"])
61
61
  detection = projects.detect { |p| (Date.today - 2.years) < Date.parse(p.last_activity_at) }
62
62
  namespace_may_be_available if detection.nil?
63
63
  namespace_not_available
@@ -199,7 +199,7 @@ module Readiness
199
199
  <li>Level of Urgency: #{request_priority}</li>
200
200
  <li>#{Readiness::SupportSuperFormProcessor::Shared.sfdc_account_string(sfdc_account)}</li>
201
201
  <li>#{Readiness::SupportSuperFormProcessor::Shared.sfdc_opportunity_string(sfdc_opportunity)}</li>
202
- <li>#{collab_project.empty? ? 'No collaboration project project' | "<a href='#{collab_project}' target='_blank'>Collaboration Project</a>"}</li>
202
+ <li>#{collab_project.empty? ? 'No collaboration project project' : "<a href='#{collab_project}' target='_blank'>Collaboration Project</a>"}</li>
203
203
  </ul>
204
204
  <p>
205
205
  What is expected from Support?
@@ -23,7 +23,7 @@ module Readiness
23
23
  org_does_not_exist if org.is_a? Hash
24
24
  new_org = Readiness::Zendesk::Organizations.new
25
25
  new_org.id = org.id
26
- new_org.custom_fields = {
26
+ new_org.organization_fields = {
27
27
  "am_project_id" => collaboriation_project_id
28
28
  }
29
29
  Readiness::Zendesk::Organizations.update!(@zendesk_client, new_org)
@@ -26,7 +26,7 @@ module Readiness
26
26
  invalid_agent unless agent_valid?
27
27
  new_org = Readiness::Zendesk::Organizations.new
28
28
  new_org.id = org.id
29
- new_org.custom_fields = {
29
+ new_org.organization_fields = {
30
30
  "assigned_se" => agent_info
31
31
  }
32
32
  Readiness::Zendesk::Organizations.update!(@zendesk_client, new_org)
@@ -48,6 +48,7 @@ module Readiness
48
48
  require "#{__dir__}/support_super_form_processor/gratis_support_upgrade"
49
49
  require "#{__dir__}/support_super_form_processor/namespace_availability"
50
50
  require "#{__dir__}/support_super_form_processor/pd_shadow_modification"
51
+ require "#{__dir__}/support_super_form_processor/sa_request_for_support"
51
52
  require "#{__dir__}/support_super_form_processor/team_member_license"
52
53
  require "#{__dir__}/support_super_form_processor/two_fa_exemption"
53
54
  require "#{__dir__}/support_super_form_processor/usgov_ir_order_management"
@@ -0,0 +1,289 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module Readiness.
4
+ module Readiness
5
+ # Defines the module TicketProcessor
6
+ module TicketProcessor
7
+ ##
8
+ # Defines the class AccountBlocked within the module {Readiness::Zendesk}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.44
12
+ class AccountBlocked < Readiness::Client
13
+ ##
14
+ # Process a Blocked Account request
15
+ #
16
+ # @author Jason Colyer
17
+ # @since 1.0.44
18
+ def self.process!(zendesk_client, gitlab_client, gitlab_admin_client, ticket_id)
19
+ @zendesk_client = zendesk_client
20
+ @gitlab_client = gitlab_client
21
+ @gitlab_admin_client = gitlab_admin_client
22
+ @ticket_id = ticket_id
23
+ @ticket = Readiness::Zendesk::Tickets.find(@zendesk_client, @ticket_id)
24
+ puts 'No ticket found, so nothing to autowork' if @ticket.is_a? Hash
25
+ exit 0 if @ticket.is_a? Hash
26
+
27
+ email = @ticket.custom_fields.detect { |t| t['id'] == 4413932829586 }['value']
28
+ puts 'No email in the field, so nothing to autowork' if email.to_s = ''
29
+ exit 0 if email.to_s = ''
30
+
31
+ search = Readiness::GitLab::Users.search_by_email(@gitlab_admin_client, email)
32
+ @user = search.detect { |s| s.email.downcase == email.downcase }
33
+ if @user.nil?
34
+ print 'No user found, updating ticket...'
35
+ new_ticket = Readiness::Zendesk::Tickets.new
36
+ new_ticket.id = @ticket.id
37
+ new_ticket.status = 'pending'
38
+ new_ticket.comment = { body: no_user_comment(email) }
39
+ new_ticket.custom_fields = [
40
+ { id: 360020735259, value: 'stage-frt' }
41
+ ]
42
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
43
+ puts 'done'
44
+ else
45
+ if %w[blocked banned].include? @user.state
46
+ if @user.note =~ /Sanctioned Location/i
47
+ print 'Blocked by embargo, updating ticket...'
48
+ new_ticket = Readiness::Zendesk::Tickets.new
49
+ new_ticket.id = @ticket.id
50
+ new_ticket.status = 'solved'
51
+ new_ticket.comment = { body: embargo_comment }
52
+ new_ticket.custom_fields = [
53
+ { id: 360020735259, value: 'stage-frt' }
54
+ ]
55
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
56
+ puts 'done'
57
+ elsif @user.note =~ /^User blocked as part of GitLab PS user migration/
58
+ @requester = Readiness::Zendesk::Users.find!(@zendesk_client, @ticket.requester_id)
59
+ search = Readiness::GitLab::Users.search_by_email(@gitlab_admin_client, @requester.email)
60
+ @requster_gitlab = search.detect { |s| s.email.downcase == @requester.email.downcase }
61
+ return failed_ps_block if @requester_gitlab.nil?
62
+
63
+ memberships = Readiness::GitLab::Users.memberships(@gitlab_admin_client, @requester, ['type=Namespace'])
64
+ has_paid = false
65
+ memberships.select { |m| m['access_level'] == 50 }.each do |m|
66
+ namespace = Readiness::GitLab::Namespaces.find(@gitlab_admin_client, m['source_id'])
67
+ next if namespace.is_a? Hash
68
+
69
+ has_paid = Readiness::GitLab::Namespaces.is_paid?(@gitlab_admin_client, namespace)
70
+ break if has_paid
71
+ end
72
+ return failed_ps_block unless has_paid
73
+
74
+ print 'Blocked by PS, unblocking and updating ticket...'
75
+ Readiness::GitLab::Users.unblock!(@gitlab_admin_client, @user)
76
+ new_user = Readiness::GitLab::Users.new
77
+ new_user.id = @user.id
78
+ new_user.note = "PS migration block removed automatically via ticket ##{@ticket.id}"
79
+ Readiness::GitLab::Users.update!(@gitlab_admin_client, new_user)
80
+ new_ticket = Readiness::Zendesk::Tickets.new
81
+ new_ticket.id = @ticket.id
82
+ new_ticket.status = 'solved'
83
+ new_ticket.comment = { body: ps_block_removed }
84
+ new_ticket.custom_fields = [
85
+ { id: 360020735259, value: 'stage-frt' }
86
+ ]
87
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
88
+ puts 'done'
89
+ else
90
+ print 'Legit block, creating T&S issue...'
91
+ project = Readiness::GitLab::Projects.find!(@gitlab_client, 40182479)
92
+ issue = Readiness::GitLab::Issues.new
93
+ issue.title = "Account Reinstatement - #{@user.username}"
94
+ issue.description = blocked_issue_body
95
+ created = Readiness::GitLab::Issues.create!(@gitlab_client, issue)
96
+ puts 'done'
97
+ print 'Updating ticket...'
98
+
99
+ new_ticket = Readiness::Zendesk::Tickets.new
100
+ new_ticket.id = @ticket.id
101
+ new_ticket.comment = { body: blocked_user_comment(created), public: false }
102
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
103
+ puts 'done'
104
+ end
105
+ else
106
+ print 'User is not blocked, updating ticket...'
107
+ new_ticket = Readiness::Zendesk::Tickets.new
108
+ new_ticket.id = @ticket.id
109
+ new_ticket.status = 'pending'
110
+ new_ticket.comment = { body: not_blocked_comment }
111
+ new_ticket.custom_fields = [
112
+ { id: 360020735259, value: 'stage-frt' }
113
+ ]
114
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
115
+ puts 'done'
116
+ end
117
+ puts 'Just right'
118
+ end
119
+ end
120
+
121
+ def self.failed_ps_block
122
+ print 'PS block, but user is not qualified to request release, updating ticket...'
123
+ new_ticket = Readiness::Zendesk::Tickets.new
124
+ new_ticket.id = @ticket.id
125
+ new_ticket.status = 'solved'
126
+ new_ticket.comment = { body: ps_block_rejected_comment }
127
+ new_ticket.custom_fields = [
128
+ { id: 360020735259, value: 'stage-frt' }
129
+ ]
130
+ Readiness::Zendesk::Tickets.update!(@zendesk_client, new_ticket)
131
+ puts 'done'
132
+ end
133
+
134
+ def self.no_user_comment(email)
135
+ <<~STRING
136
+ Hi,
137
+
138
+ Thanks for contacting GitLab Support.
139
+
140
+ Could you please let us know whether you've registered an account #{email} on GitLab.com or on a self-hosted GitLab instance?
141
+
142
+ If the account was registered on GitLab.com, please confirm the username and email address, as we cannot find an account under your email or the username you've provided.
143
+
144
+ If the account was registered on a self-hosted GitLab instance (e.g., `gitlab.yourcompany.com`), please reach out to an administrator of that instance, as it is managed separately from GitLab.com.
145
+ STRING
146
+ end
147
+
148
+ def self.not_blocked_comment
149
+ <<~STRING
150
+ Hi,
151
+
152
+ Thank you for contacting GitLab support.
153
+
154
+ The account in question, #{@user.email}, is not blocked. However, the account may be locked if the system has registered too many login attempts during a short period of time. It will be locked for 30 minutes, after which it will be unlocked automatically.
155
+
156
+ On GitLab.com, we can also lock an account when there are 3 or more failed login attempts within 24 hours. Upon successful login, you may be redirected to a verification page and an email message with a 6-digit code is sent to your _primary_ email account. Please check your email (including the spam folder) for a message with a 6-digit code to unlock your account.
157
+
158
+ Please let us know if you have any further questions or are unable to receive any emails for your account.
159
+ STRING
160
+ end
161
+
162
+ def self.embargo_comment
163
+ <<~STRING
164
+ Hi,
165
+
166
+ Thanks for contacting GitLab Support.
167
+
168
+ In accordance with the guidance provided by the U.S. government, and not determined by GitLab, there may be some countries that cannot access our platform. Your account may have been blocked as the result of a recent discovery where some user access was inadvertently granted in US embargoed regions.
169
+
170
+ GitLab is unable to conduct business with individuals or companies located in US embargoed countries. This is required under US Export Regulations, as well as, our status as a federal contractor.
171
+
172
+ For more information, please visit our [Trade Compliance page](https://about.gitlab.com/handbook/people-operations/code-of-conduct/#trade-compliance-exportimport-control).
173
+
174
+ If you believe your account has been blocked in error, you may contest this action. To do this, you will need to provide:
175
+
176
+ 1. Explanation of how your IP address was connected to an embargoed country.
177
+ 1. Attach digital copies of documentation proving you do not reside in an embargoed country.
178
+
179
+ Once you have provided the requested information, GitLab will review the matter.
180
+ STRING
181
+ end
182
+
183
+ def self.blocked_category(custom_attributes)
184
+ category = custom_attributes.detect { |c| c['key'] == 'blocked_category' }
185
+ feature = custom_attributes.detect { |c| c['key'] == 'blocked_feature' }
186
+ return 'Unknown' if category.nil? || feature.nil?
187
+
188
+ "#{category} / #{feature}"
189
+ end
190
+
191
+ def self.block_sources(custom_attributes)
192
+ sources = []
193
+ omamori = custom_attributes.detect { |c| c['key'] == 'omamori_mitigation_plan' }
194
+ sources.push("Omamori ([mitigation plan](https://omamori.sec.gitlab.net/mitigation_plans/#{omamori['value']}))") unless omamori.nil?
195
+ sources.push('Bouncer') if custom_attributes.detect { |c| c['key'] == 'block_enacted_by' && c['value'] =~ /^bouncer\:/ }
196
+ sources.push('Bouncer') if custom_attributes.detect { |c| c['key'] == 'ban_enacted_by' && c['value'] =~ /^bouncer\:/ }
197
+ admin_check = custom_attributes.detect { |c| c['key'] == 'blocked_by' }
198
+ sources.push(admin_check['value'].split('/').first) unless admin_check['value'] =~ /^service\-/
199
+ autoban_check = custom_attributes.detect { |c| c['key'] == 'auto_banned_by' }
200
+ sources.push(autoban_check['value']) unless autoban_check.nil?
201
+ return 'Other (unknown)' if sources.uniq.compact.count.zero?
202
+
203
+ sources.uniq.compact.join(', ')
204
+ end
205
+
206
+ def self.blocked_user_comment(issue)
207
+ <<~STRING
208
+ Please follow the [reinstating blocked accounts workflow](https://handbook.gitlab.com/handbook/support/workflows/reinstating-blocked-accounts/) using the following Trust & Safety issue:
209
+
210
+ #{issue.web_url}
211
+ STRING
212
+ end
213
+
214
+ def self.blocked_issue_body
215
+ request = @gitlab_admin_client.connection.get "users/#{@user.id}?with_custom_attributes=true"
216
+ custom_attributes = Oj.load(request.body)['custom_attributes']
217
+ <<~STRING
218
+ ## Account Reinstatement request
219
+
220
+ Template [Instructions](https://gitlab.com/groups/gitlab-com/gl-security/security-operations/trust-and-safety/-/wikis/Account%20Reinstatements)
221
+
222
+ ---
223
+
224
+ #### **Zendesk Message:**
225
+
226
+ ```
227
+ #{@ticket.description}
228
+ ```
229
+
230
+ <table>
231
+ <tr>
232
+ <th>Account Information</th>
233
+ </tr>
234
+ <tr>
235
+ <td>
236
+
237
+ | Related information | :link: |
238
+ | --------------------------------|--------|
239
+ | **Zendesk** | https://gitlab.zendesk.com/agent/tickets/#{@ticket.id} |
240
+ | **Account URL** | [Admin link](https://gitlab.com/admin/users/#{@user.username}) / [Profile link](https://gitlab.com/#{@user.username}) |
241
+ | **Project/Group/File** | |
242
+ | **Requestor email address**. | #{@user.email} |
243
+ | **Block category/feature** | #{blocked_category(custom_attributes)} |
244
+ | **Block source(s)** | #{block_sources(custom_attributes)} |
245
+ | **Admin note on the Account** | #{@user.note} |
246
+ | **Related Issues or Incidents** | |
247
+
248
+ </td>
249
+ </tr>
250
+ </table>
251
+
252
+ /label ~"Account Reinstatement" ~"Type::Operational" ~"Status::Triage" ~"Department::Trust & Safety" ~"T&S::Operations" ~"type::internal_request" ~"priority::2"
253
+
254
+ /due tomorrow
255
+
256
+ /weight 1
257
+ STRING
258
+ end
259
+
260
+ def self.ps_block_rejected_comment
261
+ <<~STRING
262
+ Greetings,
263
+
264
+ We are not able to proceed with this request, as the user is blocked by a Professional Services migration.
265
+
266
+ To process the removal, an Owner of a top-level paid subscription must make the request.
267
+
268
+ Please consider having an Owner of a top-level paid subscription must make the request submit a new ticket to have this automted process unblock the requested user.
269
+
270
+ Thank you,
271
+
272
+ GitLab Support
273
+ STRING
274
+ end
275
+
276
+ def self.ps_block_removed_comment
277
+ <<~STRING
278
+ Greetings,
279
+
280
+ As the block on user #{@user.email} was put in place by Professional Services for a migration and you are an Owner on a top-level paid namespace, we have removed it at this time.
281
+
282
+ If that user encounters any issues logging in and accessing their account, please reply back letting us know.
283
+
284
+ GitLab Support
285
+ STRING
286
+ end
287
+ end
288
+ end
289
+ end