api_models 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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