module ZendeskAppsSupport::Validations::Manifest
Constants
- OAUTH_MANIFEST_LINK
- OAUTH_REQUIRED_FIELDS
- PARAMETER_TYPES
- REQUIRED_MANIFEST_FIELDS
- RUBY_TO_JSON
Public Class Methods
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 16 def call(package, error_on_password_parameter: false) unless package.has_file?('manifest.json') nested_manifest = package.files.find { |file| file =~ %r{\A[^/]+?/manifest\.json\Z} } if nested_manifest return [ValidationError.new(:nested_manifest, found_path: nested_manifest.relative_path)] end return [ValidationError.new(:missing_manifest)] end package.warnings << password_parameter_warning unless error_on_password_parameter collate_manifest_errors(package, error_on_password_parameter) rescue JSON::ParserError => e return [ValidationError.new(:manifest_not_json, errors: e)] rescue ZendeskAppsSupport::Manifest::OverrideError => e return [ValidationError.new(:duplicate_manifest_keys, errors: e.message)] end
Private Class Methods
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 211 def ban_framework_version(manifest) ValidationError.new(:no_framework_version_required) unless manifest.framework_version.nil? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 207 def ban_location(manifest) ValidationError.new(:no_location_required) unless manifest.location_options.empty? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 195 def ban_no_template(manifest) return unless manifest.iframe_only? no_template_migration_link = 'https://developer.zendesk.com/apps/docs/apps-v2/manifest#location' if manifest.no_template? || !manifest.no_template_locations.empty? ValidationError.new(:no_template_deprecated_in_v2, link: no_template_migration_link) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 203 def ban_parameters(manifest) ValidationError.new(:no_parameters_required) unless manifest.parameters.empty? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 166 def boolean_error(manifest) booleans = %i[requirements_only marketing_only single_install signed_urls private] errors = [] RUBY_TO_JSON.each do |ruby, json| if booleans.include? ruby errors << validate_boolean(manifest.public_send(ruby), json) end end errors.compact end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 189 def check_errors(error_types, collector, *checked_objects) error_types.each do |error_type| collector << send(error_type, *checked_objects) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 36 def collate_manifest_errors(package, error_on_password_parameter) manifest = package.manifest errors = [ missing_keys_error(manifest), type_checks(manifest), oauth_error(manifest), default_locale_error(manifest, package), validate_urls(manifest), validate_parameters(manifest), if manifest.requirements_only? || manifest.marketing_only? [ ban_location(manifest), ban_framework_version(manifest) ] else [ validate_location(package), missing_framework_version(manifest), invalid_version_error(manifest) ] end, ban_no_template(manifest), if error_on_password_parameter [ deprecate_password_parameter_type(manifest) ] end ] errors.flatten.compact end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 278 def default_locale_error(manifest, package) default_locale = manifest.default_locale unless default_locale.nil? if default_locale !~ Translations::VALID_LOCALE ValidationError.new(:invalid_default_locale, default_locale: default_locale) elsif package.translation_files.detect { |f| f.relative_path == "translations/#{default_locale}.json" }.nil? ValidationError.new(:missing_translation_file, default_locale: default_locale) end end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 215 def deprecate_password_parameter_type(manifest) secure_settings_link = 'https://developer.zendesk.com/documentation/apps/app-developer-guide/making-api-requests-from-a-zendesk-app/#using-secure-settings' if manifest.parameters.any? { |p| p.type == 'password' } ValidationError.new(:password_parameter_type_deprecated, link: secure_settings_link) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 293 def invalid_location_error(package) errors = [] package.manifest.location_options.each do |location_options| if location_options.url.is_a?(String) && !location_options.url.empty? errors << invalid_location_uri_error(package, location_options) elsif location_options.auto_load? errors << ValidationError.new(:blank_location_uri, location: location_options.location.name) end if !([true, false].include? location_options.flexible) && !location_options.flexible.nil? errors << invalid_location_flexible_error(location_options) end end Product::PRODUCTS_AVAILABLE.each do |product| invalid_locations = package.manifest.unknown_locations(product.name) next if invalid_locations.empty? errors << ValidationError.new(:invalid_location, invalid_locations: invalid_locations.join(', '), host_name: product.name.capitalize, count: invalid_locations.length) end package.manifest.unknown_hosts.each do |unknown_host| errors << ValidationError.new(:invalid_host, host_name: unknown_host) end errors end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 353 def invalid_location_flexible_error(location_options) flexible_flag = location_options.flexible validation_error = ValidationError.new(:invalid_location_flexible_type, flexible: flexible_flag) validation_error end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 340 def invalid_location_uri_error(package, location_options) path = location_options.url return nil if path == ZendeskAppsSupport::Manifest::LEGACY_URI_STUB return nil if path.include?('{{setting.') validation_error = ValidationError.new(:invalid_location_uri, uri: path) uri = URI.parse(path) unless uri.absolute? ? valid_absolute_uri?(uri) : valid_relative_uri?(package, uri) validation_error end rescue URI::InvalidURIError validation_error end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 398 def invalid_type_error(manifest) invalid_types = [] manifest.parameters.each do |parameter| parameter_type = parameter.type invalid_types << parameter_type unless PARAMETER_TYPES.include?(parameter_type) end if invalid_types.any? ValidationError.new(:invalid_type_parameter, invalid_types: invalid_types.join(', '), count: invalid_types.length) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 323 def invalid_v1_location(package) return unless package.manifest.framework_version && Gem::Version.new(package.manifest.framework_version) < Gem::Version.new('2') invalid_locations = package.manifest.location_options .map(&:location) .compact .select(&:v2_only) .map(&:name) unless invalid_locations.empty? return ValidationError.new(:invalid_v1_location, invalid_locations: invalid_locations.join(', '), count: invalid_locations.length) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 371 def invalid_version_error(manifest) valid_to_serve = AppVersion::TO_BE_SERVED target_version = manifest.framework_version unless valid_to_serve.include?(target_version) return ValidationError.new(:invalid_version, target_version: target_version, available_versions: valid_to_serve.join(', ')) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 429 def location_framework_mismatch(manifest) legacy_locations, iframe_locations = manifest.location_options.partition(&:legacy?) if manifest.iframe_only? return ValidationError.new(:locations_must_be_urls) unless legacy_locations.empty? elsif !iframe_locations.empty? return ValidationError.new(:locations_cant_be_urls) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 109 def marketing_only_errors(manifest) [ ban_parameters(manifest), private_marketing_app_error(manifest) ] end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 367 def missing_framework_version(manifest) missing_keys_validation_error([RUBY_TO_JSON[:framework_version]]) if manifest.framework_version.nil? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 270 def missing_keys_error(manifest) missing = REQUIRED_MANIFEST_FIELDS.map do |ruby_method, manifest_value| manifest_value if manifest.public_send(ruby_method).nil? end.compact missing_keys_validation_error(missing) if missing.any? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 423 def missing_keys_validation_error(missing_keys) ValidationError.new('manifest_keys.missing', missing_keys: missing_keys.join(', '), count: missing_keys.length) end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 289 def missing_location_error(package) missing_keys_validation_error(['location']) if package.manifest.location_options.empty? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 382 def name_as_parameter_name_error(manifest) if manifest.parameters.any? { |p| p.name == 'name' } ValidationError.new(:name_as_parameter_name) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 439 def no_template_format_error(manifest) no_template = manifest.no_template return if [false, true].include? no_template unless no_template.is_a?(Array) && manifest.no_template_locations.all? { |loc| Location.find_by(name: loc) } ValidationError.new(:invalid_no_template) end end
TODO: check the app actually runs in included locations
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 101 def oauth_cannot_be_secure(manifest) manifest.parameters.map do |parameter| if parameter.type == 'oauth' && parameter.secure return ValidationError.new('oauth_parameter_cannot_be_secure') end end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 226 def oauth_error(manifest) return unless manifest.oauth oauth_errors = [] missing = OAUTH_REQUIRED_FIELDS.select do |key| manifest.oauth[key].nil? || manifest.oauth[key].empty? end if missing.any? oauth_errors << \ ValidationError.new('oauth_keys.missing', missing_keys: missing.join(', '), count: missing.length) end unless manifest.parameters.any? { |param| param.type == 'oauth' } oauth_errors << ValidationError.new('oauth_parameter_required', link: OAUTH_MANIFEST_LINK) end oauth_errors end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 245 def parameters_error(manifest) original = manifest.original_parameters unless original.nil? || original.is_a?(Array) return ValidationError.new(:parameters_not_an_array) end return unless manifest.parameters.any? para_names = manifest.parameters.map(&:name) duplicate_parameters = para_names.select { |name| para_names.count(name) > 1 }.uniq unless duplicate_parameters.empty? return ValidationError.new(:duplicate_parameters, duplicate_parameters: duplicate_parameters) end invalid_required = manifest.parameters.map do |parameter| validate_boolean(parameter.required, "parameters.#{parameter.name}.required") end.compact return invalid_required if invalid_required.any? invalid_secure = manifest.parameters.map do |parameter| validate_boolean(parameter.secure, "parameters.#{parameter.name}.secure") end.compact return invalid_secure if invalid_secure.any? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 455 def password_parameter_warning I18n.t( 'txt.apps.admin.error.app_build.translation.password_parameter_deprecated', link: 'https://developer.zendesk.com/documentation/apps/app-developer-guide/making-api-requests-from-a-zendesk-app/#using-basic-access-authentication' ) end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 222 def private_marketing_app_error(manifest) ValidationError.new(:marketing_only_app_cant_be_private) if manifest.private? end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 144 def string_error(manifest) manifest_strings = %i[ default_locale version framework_version remote_installation_url terms_conditions_url google_analytics_code ] errors = manifest_strings.map do |field| validate_string(manifest.public_send(field), field) end if manifest.author author_strings = %w[name email url] errors << (author_strings.map do |field| validate_string(manifest.author[field], "author #{field}") end) end errors end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 413 def too_many_oauth_parameters(manifest) oauth_parameters = manifest.parameters.select do |parameter| parameter.type == 'oauth' end if oauth_parameters.count > 1 ValidationError.new(:too_many_oauth_parameters) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 116 def type_checks(manifest) errors = [ boolean_error(manifest), string_error(manifest), no_template_format_error(manifest) ] unless manifest.experiments.is_a?(Hash) errors << ValidationError.new( :unacceptable_hash, field: 'experiments', value: manifest.experiments.class.to_s ) end whitelist = manifest.domain_whitelist unless whitelist.nil? || whitelist.is_a?(Array) && whitelist.all? { |dom| dom.is_a? String } errors << ValidationError.new(:unacceptable_array_of_strings, field: 'domainWhitelist') end parameters = manifest.original_parameters unless parameters.nil? || parameters.is_a?(Array) errors << ValidationError.new( :unacceptable_array, field: 'parameters', value: parameters.class.to_s ) end errors end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 359 def valid_absolute_uri?(uri) uri.scheme == 'https' || uri.host == 'localhost' end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 363 def valid_relative_uri?(package, uri) uri.path.start_with?('assets/') && package.has_file?(uri.path) end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 447 def valid_url?(value) uri = URI.parse(value) host_empty = uri.host.nil? || uri.host == '' uri.is_a?(URI::HTTP) && !host_empty rescue URI::InvalidURIError false end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 183 def validate_boolean(value, label_for_error) unless [true, false].include? value ValidationError.new(:unacceptable_boolean, field: label_for_error, value: value) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 62 def validate_location(package) manifest = package.manifest [ missing_location_error(package), invalid_location_error(package), invalid_v1_location(package), location_framework_mismatch(manifest) ] end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 86 def validate_parameters(manifest) if manifest.marketing_only? marketing_only_errors(manifest) else [ parameters_error(manifest), invalid_hidden_parameter_error(manifest), invalid_type_error(manifest), too_many_oauth_parameters(manifest), oauth_cannot_be_secure(manifest), name_as_parameter_name_error(manifest) ] end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 177 def validate_string(value, label_for_error) unless value.is_a?(String) || value.nil? ValidationError.new(:unacceptable_string, field: label_for_error, value: value) end end
Source
# File lib/zendesk_apps_support/validations/manifest.rb, line 72 def validate_urls(manifest) errors = [] if manifest.terms_conditions_url && !valid_url?(manifest.terms_conditions_url) errors << ValidationError.new(:invalid_url, field: 'terms_conditions_url', value: manifest.terms_conditions_url) end author = manifest.author if author && author["url"] && !valid_url?(author["url"]) errors << ValidationError.new(:invalid_url, field: 'author url', value: author["url"]) end errors end