@@ -11,9 +11,10 @@ module Manifest
1111 OAUTH_REQUIRED_FIELDS = %w[ client_id client_secret authorize_uri access_token_uri ] . freeze
1212 PARAMETER_TYPES = ZendeskAppsSupport ::Manifest ::Parameter ::TYPES
1313 OAUTH_MANIFEST_LINK = 'https://developer.zendesk.com/apps/docs/developer-guide/manifest#oauth'
14+ SECURE_PARAM_SCOPES = %w[ header body url_host url_path jwt_secret_key jwt_claim basic_auth_username basic_auth_password ] . freeze
1415
1516 class << self
16- def call ( package , error_on_password_parameter : false )
17+ def call ( package , error_on_password_parameter : false , validate_scopes_for_secure_parameter : false )
1718 unless package . has_file? ( 'manifest.json' )
1819 nested_manifest = package . files . find { |file | file =~ %r{\A [^/]+?/manifest\. json\Z } }
1920 if nested_manifest
@@ -24,7 +25,7 @@ def call(package, error_on_password_parameter: false)
2425
2526 package . warnings << password_parameter_warning if !error_on_password_parameter && password_param_present? ( package . manifest )
2627
27- collate_manifest_errors ( package , error_on_password_parameter )
28+ collate_manifest_errors ( package , error_on_password_parameter , validate_scopes_for_secure_parameter )
2829 rescue JSON ::ParserError => e
2930 return [ ValidationError . new ( :manifest_not_json , errors : e ) ]
3031 rescue ZendeskAppsSupport ::Manifest ::OverrideError => e
@@ -37,7 +38,7 @@ def password_param_present?(manifest)
3738 manifest . parameters . any? { |p | p . type == 'password' }
3839 end
3940
40- def collate_manifest_errors ( package , error_on_password_parameter )
41+ def collate_manifest_errors ( package , error_on_password_parameter , validate_scopes_for_secure_parameter )
4142 manifest = package . manifest
4243
4344 errors = [
@@ -46,7 +47,7 @@ def collate_manifest_errors(package, error_on_password_parameter)
4647 oauth_error ( manifest ) ,
4748 default_locale_error ( manifest , package ) ,
4849 validate_urls ( manifest ) ,
49- validate_parameters ( manifest ) ,
50+ validate_parameters ( manifest , validate_scopes_for_secure_parameter ) ,
5051 if manifest . requirements_only? || manifest . marketing_only?
5152 [ ban_location ( manifest ) ,
5253 ban_framework_version ( manifest ) ]
@@ -87,7 +88,7 @@ def validate_urls(manifest)
8788 errors
8889 end
8990
90- def validate_parameters ( manifest )
91+ def validate_parameters ( manifest , validate_scopes_for_secure_parameter )
9192 if manifest . marketing_only?
9293 marketing_only_errors ( manifest )
9394 else
@@ -97,7 +98,8 @@ def validate_parameters(manifest)
9798 invalid_type_error ( manifest ) ,
9899 too_many_oauth_parameters ( manifest ) ,
99100 oauth_cannot_be_secure ( manifest ) ,
100- name_as_parameter_name_error ( manifest )
101+ name_as_parameter_name_error ( manifest ) ,
102+ *( validate_scopes_for_secure_parameter ? invalid_secure_param_scopes_errors ( manifest ) : invalid_scopes_key_error ( manifest ) ) ,
101103 ]
102104 end
103105 end
@@ -110,6 +112,52 @@ def oauth_cannot_be_secure(manifest)
110112 end
111113 end
112114
115+ def invalid_scopes_key_error ( manifest )
116+ errors = [ ]
117+ manifest . parameters . each do |parameter |
118+ next if parameter . scopes . nil?
119+
120+ errors << ValidationError . new ( :field_contains_invalid_keys ,
121+ field : "parameters[name=\" #{ parameter . name } \" ]" ,
122+ keys : 'scopes' )
123+ end
124+ errors
125+ end
126+
127+ def invalid_secure_param_scopes_errors ( manifest )
128+ errors = [ ]
129+
130+ manifest . parameters . each do |parameter |
131+ next if parameter . scopes . nil?
132+
133+ unless parameter . secure
134+ errors << ValidationError . new ( :field_requires_secure_parameter , field : "parameters[name=\" #{ parameter . name } \" ].scopes" )
135+ end
136+
137+ unless parameter . scopes . is_a? ( Array )
138+ errors << ValidationError . new ( :unacceptable_array ,
139+ field : "parameters[name=\" #{ parameter . name } \" ].scopes" ,
140+ value : parameter . scopes . class . to_s )
141+ next
142+ end
143+
144+ if parameter . scopes . empty?
145+ errors << ValidationError . new ( :field_cannot_be_empty , field : "parameters[name=\" #{ parameter . name } \" ].scopes" )
146+ end
147+
148+ invalid_scopes = parameter . scopes - SECURE_PARAM_SCOPES
149+ if invalid_scopes . any?
150+ errors << ValidationError . new (
151+ :field_contains_invalid_values ,
152+ field : "parameters[name=\" #{ parameter . name } \" ].scopes" ,
153+ values : invalid_scopes . join ( I18n . t ( 'txt.apps.admin.error.app_build.listing_comma' ) )
154+ )
155+ end
156+ end
157+
158+ errors
159+ end
160+
113161 def marketing_only_errors ( manifest )
114162 [
115163 ban_parameters ( manifest ) ,
@@ -261,12 +309,12 @@ def parameters_error(manifest)
261309 end
262310
263311 invalid_required = manifest . parameters . map do |parameter |
264- validate_boolean ( parameter . required , "parameters. #{ parameter . name } .required" )
312+ validate_boolean ( parameter . required , "parameters[name= \" #{ parameter . name } \" ] .required" )
265313 end . compact
266314 return invalid_required if invalid_required . any?
267315
268316 invalid_secure = manifest . parameters . map do |parameter |
269- validate_boolean ( parameter . secure , "parameters. #{ parameter . name } .secure" )
317+ validate_boolean ( parameter . secure , "parameters[name= \" #{ parameter . name } \" ] .secure" )
270318 end . compact
271319 return invalid_secure if invalid_secure . any?
272320 end
0 commit comments