api_models 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +2 -0
  4. data/lib/api_models/version.rb +5 -0
  5. data/lib/api_models.rb +68 -0
  6. data/lib/models/account.rb +39 -0
  7. data/lib/models/agent.rb +439 -0
  8. data/lib/models/app.rb +18 -0
  9. data/lib/models/app47_cache.rb +69 -0
  10. data/lib/models/app_active_build.rb +32 -0
  11. data/lib/models/app_policy.rb +24 -0
  12. data/lib/models/app_shield_policy.rb +35 -0
  13. data/lib/models/authorized_user_policy.rb +44 -0
  14. data/lib/models/b2b_app.rb +8 -0
  15. data/lib/models/cat/customer.rb +9 -0
  16. data/lib/models/cat/customer_device.rb +10 -0
  17. data/lib/models/cl/customer.rb +9 -0
  18. data/lib/models/cl/customer_device.rb +10 -0
  19. data/lib/models/commerce_app_store.rb +8 -0
  20. data/lib/models/concerns/app47_app_analyzable.rb +46 -0
  21. data/lib/models/concerns/app47_app_buildable.rb +46 -0
  22. data/lib/models/concerns/app47_app_configurable.rb +34 -0
  23. data/lib/models/concerns/app47_app_policies.rb +59 -0
  24. data/lib/models/concerns/app47_cdn_url.rb +50 -0
  25. data/lib/models/concerns/app47_email_sendable.rb +29 -0
  26. data/lib/models/concerns/app47_logger.rb +109 -0
  27. data/lib/models/concerns/checkin_able.rb +28 -0
  28. data/lib/models/concerns/searchable.rb +54 -0
  29. data/lib/models/configuration_constraint.rb +22 -0
  30. data/lib/models/configuration_group.rb +50 -0
  31. data/lib/models/configuration_rule.rb +58 -0
  32. data/lib/models/device.rb +124 -0
  33. data/lib/models/external_app.rb +15 -0
  34. data/lib/models/gehc/customer.rb +17 -0
  35. data/lib/models/gehc/customer_device.rb +23 -0
  36. data/lib/models/group.rb +40 -0
  37. data/lib/models/internal_app.rb +11 -0
  38. data/lib/models/metric_data_job.rb +16 -0
  39. data/lib/models/option.rb +37 -0
  40. data/lib/models/pin_code_policy.rb +50 -0
  41. data/lib/models/platform.rb +26 -0
  42. data/lib/models/platform_model.rb +14 -0
  43. data/lib/models/product_app.rb +22 -0
  44. data/lib/models/product_support_app.rb +19 -0
  45. data/lib/models/queue_manager.rb +67 -0
  46. data/lib/models/redis_configuration.rb +137 -0
  47. data/lib/models/sso_ad_group.rb +7 -0
  48. data/lib/models/sso_ad_server.rb +13 -0
  49. data/lib/models/sso_ad_user.rb +13 -0
  50. data/lib/models/sso_azure_server.rb +18 -0
  51. data/lib/models/sso_directory_group.rb +13 -0
  52. data/lib/models/sso_directory_server.rb +21 -0
  53. data/lib/models/sso_google_server.rb +13 -0
  54. data/lib/models/sso_ldap_group.rb +8 -0
  55. data/lib/models/sso_ldap_rest_server.rb +34 -0
  56. data/lib/models/sso_ldap_server.rb +19 -0
  57. data/lib/models/sso_ldap_user.rb +7 -0
  58. data/lib/models/sso_oauth_server.rb +16 -0
  59. data/lib/models/sso_saml_v2_server.rb +25 -0
  60. data/lib/models/sso_server.rb +38 -0
  61. data/lib/models/sso_user.rb +13 -0
  62. data/lib/models/system_configuration.rb +92 -0
  63. data/lib/models/time_bomb_policy.rb +138 -0
  64. data/lib/models/user.rb +53 -0
  65. data/lib/models/user_app_permission.rb +16 -0
  66. data/lib/models/user_device.rb +83 -0
  67. data/lib/models/version_management_policy.rb +113 -0
  68. data/lib/models/web_app.rb +12 -0
  69. metadata +408 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Base class for an app policy
5
+ #
6
+ class AppPolicy
7
+ include Mongoid::Document
8
+ include Mongoid::Timestamps
9
+ #
10
+ # Fields
11
+ #
12
+ field :active, type: Boolean, default: false
13
+ field :message, type: String
14
+ #
15
+ # Relationships
16
+ #
17
+ belongs_to :app, inverse_of: :policies
18
+ #
19
+ # return the policy hash for this agent
20
+ #
21
+ def enforce_policy(_agent)
22
+ {}
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Is the user allowed use this device
5
+ #
6
+ class AppShieldPolicy < AppPolicy
7
+ #
8
+ # iOS fields
9
+ #
10
+ field :ios_debug, type: Boolean, default: false
11
+ field :ios_jail_break, type: Boolean, default: false
12
+ field :ios_hooking_frameworks, type: Boolean, default: false
13
+ field :ios_repackaging, type: Boolean, default: false
14
+ field :ios_user_screenshot, type: Boolean, default: false
15
+ field :ios_system_screenshot, type: Boolean, default: false
16
+ field :ios_run_time_library, type: Boolean, default: false
17
+ field :ios_library_injection, type: Boolean, default: false
18
+ field :ios_keyboard_cache_monitor, type: Boolean, default: false
19
+ field :ios_block_external_screens, type: Boolean, default: false
20
+ # Android fields
21
+ field :android_debug, type: Boolean, default: false
22
+ field :android_jail_break, type: Boolean, default: false
23
+ field :android_hooking_frameworks, type: Boolean, default: false
24
+ field :android_repackaging, type: Boolean, default: false
25
+ field :android_user_screenshot, type: Boolean, default: false
26
+ field :android_system_screenshot, type: Boolean, default: false
27
+ field :android_run_time_library, type: Boolean, default: false
28
+ field :android_library_injection, type: Boolean, default: false
29
+ field :android_keyboard_cache_monitor, type: Boolean, default: false
30
+ field :android_block_external_screens, type: Boolean, default: false
31
+
32
+ def enforce_policy(_agent)
33
+ {}
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # If this app requires an authorized user
5
+ #
6
+ class AuthorizedUserPolicy < AppPolicy
7
+ #
8
+ # fields
9
+ #
10
+ field :wipe_app_data, type: Boolean, default: false
11
+
12
+ #
13
+ # return the policy hash for this agent
14
+ #
15
+ def enforce_policy(agent)
16
+ policy = super.merge(device_enabled: 1)
17
+ if active? && !user_can_run_app?(agent)
18
+ policy[:device_enabled] = 0
19
+ policy[:device_disabled_message] = message
20
+ policy[:wipe_app_data] = wipe_app_data
21
+ end
22
+ policy
23
+ rescue StandardError
24
+ # Return the default policy
25
+ { device_enabled: 1 }
26
+ end
27
+
28
+ private
29
+
30
+ #
31
+ # can this user run this app?
32
+ # We first find the user by the agent's device unique identifier
33
+ # then we make sure hte user has access to that application.
34
+ #
35
+ def user_can_run_app?(agent)
36
+ user = agent.find_user
37
+ device_identifier = agent.device.unique_identifier
38
+ device = user.find_device_by device_identifier
39
+ device.present? && device.approved? && user.allowed_app_set.include?(app)
40
+ rescue StandardError
41
+ # On failure, say no
42
+ false
43
+ end
44
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # An B2bApp app supports the iTunes B2B program, basically a place holder for VPP codes.
5
+ #
6
+ class B2bApp < App
7
+ include App47AppAnalyzable
8
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Caterpillar customer
5
+ #
6
+ module Cat
7
+ class Customer < User
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cat
4
+ #
5
+ # Caterpillar customer device
6
+ #
7
+ class CustomerDevice < ::UserDevice
8
+ field :toolbox_app_id, type: String
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # CloudLink Customer
5
+ #
6
+ module Cl
7
+ class Customer < User
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cl
4
+ #
5
+ # Cloudlink customer device
6
+ #
7
+ class CustomerDevice < UserDevice
8
+ field :toolbox_app_id, type: String
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Type of app that is a commerce app store container
5
+ #
6
+ class CommerceAppStore < ProductApp
7
+ include App47AppPolicies
8
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Apps that are analyazble, i.e., they have an agent associated
5
+ # with them. For now, web apps and internal apps have these
6
+ # properties.
7
+ #
8
+ module App47AppAnalyzable
9
+ extend ActiveSupport::Concern
10
+ #
11
+ # Add fields, relationships and callbacks
12
+ #
13
+ def self.included(base)
14
+ base.class_eval do
15
+ #
16
+ # Fields
17
+ #
18
+ field :usage_ranking, type: Integer, default: 0
19
+ field :analyzable, type: Boolean, default: true
20
+ field :agent_count, type: Integer, default: 0
21
+ field :agent_log_level, type: String, default: 'Info'
22
+ field :agent_capture_timed_events, type: Boolean, default: true
23
+ field :agent_capture_generic_events, type: Boolean, default: true
24
+ field :agent_capture_sessions, type: Boolean, default: true
25
+ field :agent_enabled, type: Boolean, default: true
26
+ field :agent_upload_on_exit, type: Boolean, default: true
27
+ field :agent_capture_crash_format, type: String, default: 'none'
28
+ field :agent_delay_data_upload_interval, type: Integer, default: 1
29
+ field :agent_configuration_update_frequency, type: Float, default: 1
30
+ field :agent_session_threshold_seconds, type: Integer, default: 5
31
+ #
32
+ # Relationships
33
+ #
34
+ has_many :agents, dependent: :destroy, inverse_of: :app
35
+
36
+ #
37
+ # Is the api enabled for this app?
38
+ #
39
+ def api_enabled?
40
+ agent_enabled? && account.api_enabled?
41
+ rescue StandardError
42
+ false
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Applications that have builds
5
+ #
6
+ module App47AppBuildable
7
+ extend ActiveSupport::Concern
8
+ TRACKED_VERSION = 'version' unless defined? TRACKED_VERSION
9
+ TRACKED_VERSION_CODE = 'version_code' unless defined? TRACKED_VERSION_CODE
10
+ ALL_TRACKED_VERSIONS = [TRACKED_VERSION, TRACKED_VERSION_CODE].freeze unless defined? ALL_TRACKED_VERSIONS
11
+ #
12
+ # Add methods to class
13
+ #
14
+ def self.included(base)
15
+ base.class_eval do
16
+ #
17
+ # Fields
18
+ #
19
+ field :notify_users_on_build_activation, type: Boolean, default: true
20
+ field :max_builds, type: Integer, default: 10
21
+ field :buildable, type: Boolean, default: true
22
+ field :ios_tracked_version, type: String, default: TRACKED_VERSION
23
+ field :android_tracked_version, type: String, default: TRACKED_VERSION
24
+ #
25
+ # Relationships
26
+ #
27
+ has_many :app_active_builds, dependent: :destroy, inverse_of: :app
28
+
29
+ #
30
+ # Return what the tracked version is for this Buildable abject, either version or version code
31
+ #
32
+ def tracked_version(platform)
33
+ send("#{platform.downcase}_tracked_version")
34
+ rescue StandardError
35
+ TRACKED_VERSION
36
+ end
37
+
38
+ #
39
+ # Should use the version code for this app on the given platform
40
+ #
41
+ def use_version_code?(platform)
42
+ TRACKED_VERSION_CODE.eql?(tracked_version(platform))
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # An app that can have a configuration
5
+ #
6
+ module App47AppConfigurable
7
+ extend ActiveSupport::Concern
8
+ #
9
+ # Add methods to class
10
+ #
11
+ def self.included(base)
12
+ base.class_eval do
13
+ #
14
+ # Relationships
15
+ #
16
+ has_many :configuration_groups, dependent: :destroy, inverse_of: :app do
17
+ #
18
+ # Return configuration groups that match the agent
19
+ #
20
+ def match_agent(agent)
21
+ where(active: true).collect do |group|
22
+ next unless group.match_agent?(agent)
23
+
24
+ { version: group.version, id: group.id.to_s }
25
+ end.compact
26
+ end
27
+ end
28
+ #
29
+ # Fields
30
+ #
31
+ field :configurable, type: Boolean, default: true
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # An app that can have a collection of security policies
5
+ #
6
+ module App47AppPolicies
7
+ extend ActiveSupport::Concern
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ has_many :policies, dependent: :destroy, class_name: 'AppPolicy', inverse_of: :app
12
+ end
13
+ end
14
+
15
+ #
16
+ # Return authorized users policy
17
+ #
18
+ def authorized_user_policy
19
+ policies.find_by!(_type: 'AuthorizedUserPolicy')
20
+ rescue StandardError
21
+ nil
22
+ end
23
+
24
+ #
25
+ # Return version management
26
+ #
27
+ def version_management_policy
28
+ policies.find_by!(_type: 'VersionManagementPolicy')
29
+ rescue StandardError
30
+ nil
31
+ end
32
+
33
+ #
34
+ # PIN Code policy
35
+ #
36
+ def pin_code_policy
37
+ policies.find_by!(_type: 'PinCodePolicy')
38
+ rescue StandardError
39
+ nil
40
+ end
41
+
42
+ #
43
+ # Time Bomb Policy
44
+ #
45
+ def time_bomb_policy
46
+ policies.find_by!(_type: 'TimeBombPolicy')
47
+ rescue StandardError
48
+ nil
49
+ end
50
+
51
+ #
52
+ # Return app shield policy
53
+ #
54
+ def app_shield_policy
55
+ policies.find_by!(_type: 'AppShieldPolicy')
56
+ rescue StandardError
57
+ nil
58
+ end
59
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Take an existing either paperclip object or database field and return
5
+ # a fully qualified cdn url for that file.
6
+ #
7
+ # If the system configuration parameter for the url is not set, then simply return the value.
8
+ #
9
+ # If it is set, then replace the prefix of the URL defined by the boundry of class name, so internal_build will be
10
+ # https://original.amazon.com/internal_builds/id/original.ipa
11
+ #
12
+ # will be transposed to:
13
+ # https://cnd.apazon.com/intenral_builds/id/original.ipa
14
+ #
15
+ # To use this, first include App47::CdnUrl in your class and then when you want the URL of an object call
16
+ # app.cdn_file_url or ubild.cdn_file_url instead of app.file_url or build.file_url.
17
+ #
18
+ #
19
+ module App47CdnUrl
20
+ #
21
+ # Handle the call to cdn_whatever
22
+ #
23
+ def method_missing(method, *args)
24
+ if method.to_s.start_with? 'cdn_'
25
+ url = send method.to_s.sub(/^cdn_/, '')
26
+ cdn_url = SystemConfiguration.cdn_url
27
+ unless cdn_url.blank? || url.blank?
28
+ model_name = "#{self.class.to_s.underscore}s"
29
+ url = "#{cdn_url}/#{model_name}/#{url.split("/#{model_name}/").last}" if url.include? "/#{model_name}/"
30
+ end
31
+ url
32
+ else
33
+ super
34
+ end
35
+ end
36
+
37
+ #
38
+ # Look for matches on cdn_
39
+ #
40
+ def respond_to_missing?(method_name, include_private = false)
41
+ method_name.to_s.start_with?('cdn_') ? true : super
42
+ end
43
+
44
+ #
45
+ # Look for matches on cdn_
46
+ #
47
+ def respond_to?(method, include_private = false)
48
+ super unless method.to_s.start_with? 'cdn_'
49
+ end
50
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Objects that emails can be sent too...
5
+ #
6
+ module App47EmailSendable
7
+ extend ActiveSupport::Concern
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ field :email, type: String
12
+ field :email_bounce_date, type: Time
13
+ field :email_bounce_reason, type: String
14
+ field :unconfirmed_email, type: String
15
+ field :email_enabled, type: Boolean, default: true
16
+
17
+ before_validation :downcase_email
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ #
24
+ # Make sure emails are always downcased
25
+ #
26
+ def downcase_email
27
+ self.email = email.strip.downcase unless email.blank?
28
+ end
29
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Mixin for App47 objects to handle logging in both the rails environment as well
5
+ # as the delayed jobs environment that doesn't know about Rails.logger
6
+ #
7
+ # Provides ways to log at the class level as well as instance level.
8
+ #
9
+ #
10
+ # Usage:
11
+ # App47Logger.log_debug('meesage')
12
+ #
13
+ # or
14
+ #
15
+ # class ClassName
16
+ # include App47Logger
17
+ #
18
+ # def method_name
19
+ # log_debug('message')
20
+ # end
21
+ #
22
+ module App47Logger
23
+ #
24
+ # Log a debug messages
25
+ #
26
+ def self.log_debug(message)
27
+ log_message :debug, message
28
+ end
29
+
30
+ #
31
+ # Log a warning messages
32
+ #
33
+ # 1. Prints the messages
34
+ # 2. If an exception is passed n
35
+ # 2a prints the exception message
36
+ # 2b prints the stack trace
37
+ #
38
+ def self.log_warn(message, exception = nil)
39
+ log_message :warn, message
40
+ log_exception :warn, exception
41
+ end
42
+
43
+ #
44
+ # Log an error messages
45
+ #
46
+ # 1. Prints the messages
47
+ # 2. If an exception is passed n
48
+ # 2a prints the exception message
49
+ # 2b prints the stack trace
50
+ #
51
+ def self.log_error(message, exception = nil)
52
+ log_message :error, message
53
+ log_exception :error, exception
54
+ end
55
+
56
+ #
57
+ # Log a given exception, but only the first 10 lines in anything but test.
58
+ #
59
+ # In testing, we want the full stack to know the test case that failed.
60
+ #
61
+ def self.log_exception(level, exception = nil, max_frame = 9)
62
+ return if exception.blank?
63
+
64
+ max_frame = -1 if ENV['RACK_ENV'].eql?('test')
65
+ log_message(level, exception.message)
66
+ exception.backtrace[0..max_frame].each { |frame| log_message(level, frame) } unless exception.backtrace.blank?
67
+ end
68
+
69
+ #
70
+ # Log a given message at the given level
71
+ #
72
+ def self.log_message(level, message)
73
+ if ENV['AWS_LAMBDA_FUNCTION_VERSION'].nil?
74
+ puts "#{level}: #{message}"
75
+ else
76
+ Logger.new($stdout).send(level, message)
77
+ end
78
+ rescue StandardError
79
+ puts "#{level}: #{message}"
80
+ end
81
+
82
+ #
83
+ # Log a debug message as part of the mixin
84
+ #
85
+ def log_message(level, message)
86
+ App47Logger.log_message level, message
87
+ end
88
+
89
+ #
90
+ # Log a debug message as part of the mixin
91
+ #
92
+ def log_debug(message)
93
+ App47Logger.log_debug message
94
+ end
95
+
96
+ #
97
+ # Log a warning message as part of the mixin
98
+ #
99
+ def log_warn(message, exception = nil)
100
+ App47Logger.log_warn message, exception
101
+ end
102
+
103
+ #
104
+ # Log an error message as part of the mixin
105
+ #
106
+ def log_error(message, exception = nil)
107
+ App47Logger.log_error message, exception
108
+ end
109
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Public: Add checkin timestamp to object
5
+ #
6
+ # Examples
7
+ #
8
+ # include CheckinAble
9
+ #
10
+ module CheckinAble
11
+ extend ActiveSupport::Concern
12
+
13
+ def self.included(base)
14
+ base.class_eval do
15
+ field :last_checkin_at, type: Time, default: Time.now.utc
16
+ set_callback :save, :before, :check_in_agent
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ #
23
+ # Update the last sign in time stamp
24
+ #
25
+ def check_in_agent
26
+ self.last_checkin_at = Time.now.utc
27
+ end
28
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Public: Add search text to an object
5
+ #
6
+ module Searchable
7
+ extend ActiveSupport::Concern
8
+
9
+ def self.included(base)
10
+ base.class_eval do
11
+ field :search_text, type: String
12
+ before_validation :update_search_text
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ #
19
+ # Internal: Update the search text
20
+ #
21
+ # Examples
22
+ #
23
+ # update_search_text
24
+ #
25
+ # Call before validation to update, changes are persisted with the object.
26
+ #
27
+ def update_search_text
28
+ return if destroyed?
29
+
30
+ items = search_fields.reject { |field| send(field.to_sym).blank? }.collect do |field|
31
+ value = send(field.to_sym)
32
+ if value.is_a? String
33
+ value.downcase
34
+ elsif value.is_a? Array
35
+ value.empty? ? nil : value.join(' ').downcase
36
+ end
37
+ end
38
+ self.search_text = items.compact.join ' '
39
+ end
40
+
41
+ #
42
+ # Internal: Which fields to add to search text
43
+ #
44
+ # Examples
45
+ #
46
+ # search_fields
47
+ # # => ['name', 'email', 'code']
48
+ #
49
+ # Return which fields should be added to search
50
+ #
51
+ def search_fields
52
+ %w[name email]
53
+ end
54
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # List of available configuration constraints that are allowed for a given configuration group.
5
+ #
6
+ class ConfigurationConstraint
7
+ include Mongoid::Document
8
+ include Mongoid::Timestamps
9
+ #
10
+ # Fields
11
+ #
12
+ field :name, type: String
13
+ #
14
+ # Relationships
15
+ #
16
+ has_many :configuration_rules
17
+ #
18
+ # Validations
19
+ #
20
+ validates_presence_of :name
21
+ validates_uniqueness_of :name
22
+ end