biovision 0.0.200518.1

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 (170) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +214 -0
  4. data/Rakefile +22 -0
  5. data/app/assets/config/biovision_manifest.js +1 -0
  6. data/app/assets/images/biovision/components/carousel/arrow-left.svg +4 -0
  7. data/app/assets/images/biovision/components/carousel/arrow-right.svg +4 -0
  8. data/app/assets/images/biovision/icons/breadcrumb-hover.svg +1 -0
  9. data/app/assets/images/biovision/icons/breadcrumb.svg +1 -0
  10. data/app/assets/images/biovision/icons/components/contact.svg +26 -0
  11. data/app/assets/images/biovision/icons/components/content.svg +20 -0
  12. data/app/assets/images/biovision/icons/components/users.svg +21 -0
  13. data/app/assets/images/biovision/icons/key.svg +16 -0
  14. data/app/assets/images/biovision/icons/log_in.svg +15 -0
  15. data/app/assets/images/biovision/icons/log_out.svg +15 -0
  16. data/app/assets/images/biovision/icons/messages/error.svg +14 -0
  17. data/app/assets/images/biovision/icons/messages/info.svg +8 -0
  18. data/app/assets/images/biovision/icons/messages/success.svg +12 -0
  19. data/app/assets/images/biovision/icons/messages/warning.svg +13 -0
  20. data/app/assets/images/biovision/icons/settings.svg +41 -0
  21. data/app/assets/images/biovision/placeholders/16x9.svg +11 -0
  22. data/app/assets/images/biovision/placeholders/1x1.svg +11 -0
  23. data/app/assets/images/biovision/placeholders/3x2.svg +11 -0
  24. data/app/assets/images/biovision/placeholders/user.svg +15 -0
  25. data/app/assets/stylesheets/biovision/admin.scss +6 -0
  26. data/app/assets/stylesheets/biovision/admin/components.scss +59 -0
  27. data/app/assets/stylesheets/biovision/admin/default.scss +57 -0
  28. data/app/assets/stylesheets/biovision/admin/layout.scss +95 -0
  29. data/app/assets/stylesheets/biovision/admin/vars.scss +56 -0
  30. data/app/assets/stylesheets/biovision/biovision.scss +134 -0
  31. data/app/assets/stylesheets/biovision/biovision/messages.scss +41 -0
  32. data/app/assets/stylesheets/biovision/components/carousel.scss +53 -0
  33. data/app/assets/stylesheets/biovision/components/forms.scss +85 -0
  34. data/app/assets/stylesheets/biovision/components/hamburger.scss +56 -0
  35. data/app/assets/stylesheets/biovision/components/lists.scss +91 -0
  36. data/app/assets/stylesheets/biovision/default.scss +57 -0
  37. data/app/assets/stylesheets/biovision/themes/default_theme.scss +2 -0
  38. data/app/assets/stylesheets/biovision/themes/default_theme/components.scss +3 -0
  39. data/app/assets/stylesheets/biovision/themes/default_theme/layout.scss +44 -0
  40. data/app/assets/stylesheets/biovision/themes/default_theme/layout/footer.scss +0 -0
  41. data/app/assets/stylesheets/biovision/themes/default_theme/layout/header.scss +39 -0
  42. data/app/assets/stylesheets/biovision/vars.scss +53 -0
  43. data/app/controllers/admin/agents_controller.rb +15 -0
  44. data/app/controllers/admin/components_controller.rb +174 -0
  45. data/app/controllers/admin/index_controller.rb +11 -0
  46. data/app/controllers/admin/ip_addresses_controller.rb +15 -0
  47. data/app/controllers/admin_controller.rb +14 -0
  48. data/app/controllers/authentication_controller.rb +79 -0
  49. data/app/controllers/concerns/authentication.rb +45 -0
  50. data/app/controllers/index_controller.rb +8 -0
  51. data/app/controllers/my/confirmations_controller.rb +2 -0
  52. data/app/controllers/my/index_controller.rb +8 -0
  53. data/app/controllers/my/profiles_controller.rb +128 -0
  54. data/app/controllers/my/recoveries_controller.rb +2 -0
  55. data/app/helpers/biovision_components_helper.rb +14 -0
  56. data/app/helpers/users_helper.rb +11 -0
  57. data/app/lib/biovision/components/base_component.rb +177 -0
  58. data/app/lib/biovision/components/component_settings.rb +30 -0
  59. data/app/lib/biovision/components/privilege_handler.rb +77 -0
  60. data/app/lib/biovision/components/track_component.rb +9 -0
  61. data/app/lib/biovision/components/users/authentication.rb +47 -0
  62. data/app/lib/biovision/components/users/code_handler.rb +23 -0
  63. data/app/lib/biovision/components/users/profile_handler.rb +12 -0
  64. data/app/lib/biovision/components/users/registration_handler.rb +99 -0
  65. data/app/lib/biovision/components/users_component.rb +47 -0
  66. data/app/lib/biovision/notifiers/base_notifier.rb +69 -0
  67. data/app/lib/biovision/notifiers/socialization_notifier.rb +31 -0
  68. data/app/lib/biovision/notifiers/users_notifier.rb +15 -0
  69. data/app/models/agent.rb +35 -0
  70. data/app/models/biovision_component.rb +45 -0
  71. data/app/models/biovision_component_user.rb +21 -0
  72. data/app/models/browser.rb +34 -0
  73. data/app/models/code.rb +71 -0
  74. data/app/models/concerns/checkable.rb +22 -0
  75. data/app/models/concerns/flat_priority.rb +50 -0
  76. data/app/models/concerns/has_language.rb +10 -0
  77. data/app/models/concerns/has_owner.rb +22 -0
  78. data/app/models/concerns/has_simple_image.rb +18 -0
  79. data/app/models/concerns/has_track.rb +10 -0
  80. data/app/models/concerns/has_uuid.rb +12 -0
  81. data/app/models/concerns/meta_texts.rb +16 -0
  82. data/app/models/concerns/nested_priority.rb +58 -0
  83. data/app/models/concerns/required_unique_name.rb +16 -0
  84. data/app/models/concerns/required_unique_slug.rb +15 -0
  85. data/app/models/concerns/toggleable.rb +33 -0
  86. data/app/models/foreign_site.rb +34 -0
  87. data/app/models/foreign_user.rb +21 -0
  88. data/app/models/ip_address.rb +31 -0
  89. data/app/models/language.rb +31 -0
  90. data/app/models/login_attempt.rb +35 -0
  91. data/app/models/metric.rb +48 -0
  92. data/app/models/metric_value.rb +11 -0
  93. data/app/models/notification.rb +37 -0
  94. data/app/models/simple_image.rb +47 -0
  95. data/app/models/simple_image_tag.rb +30 -0
  96. data/app/models/simple_image_tag_image.rb +13 -0
  97. data/app/models/token.rb +96 -0
  98. data/app/models/user.rb +136 -0
  99. data/app/models/user_language.rb +15 -0
  100. data/app/uploaders/simple_image_uploader.rb +96 -0
  101. data/app/uploaders/user_image_uploader.rb +58 -0
  102. data/app/views/admin/agents/_nav_item.html.erb +6 -0
  103. data/app/views/admin/agents/entity/_in_list.html.erb +6 -0
  104. data/app/views/admin/agents/index.html.erb +13 -0
  105. data/app/views/admin/components/_list.html.erb +12 -0
  106. data/app/views/admin/components/entity/_links.html.erb +35 -0
  107. data/app/views/admin/components/entity/_section.html.erb +12 -0
  108. data/app/views/admin/components/index.html.erb +12 -0
  109. data/app/views/admin/components/links/_track.html.erb +2 -0
  110. data/app/views/admin/components/links/_users.html.erb +11 -0
  111. data/app/views/admin/components/privileges.html.erb +20 -0
  112. data/app/views/admin/components/privileges/_component_user.html.erb +17 -0
  113. data/app/views/admin/components/privileges/_links.html.erb +35 -0
  114. data/app/views/admin/components/privileges/_privilege_flag.html.erb +28 -0
  115. data/app/views/admin/components/privileges/_users.html.erb +23 -0
  116. data/app/views/admin/components/settings.html.erb +39 -0
  117. data/app/views/admin/components/settings/_new_parameter.html.erb +46 -0
  118. data/app/views/admin/components/settings/_parameters.html.erb +20 -0
  119. data/app/views/admin/components/settings/_setting.html.erb +18 -0
  120. data/app/views/admin/components/settings/_settings.html.erb +31 -0
  121. data/app/views/admin/components/show.html.erb +14 -0
  122. data/app/views/admin/index/index.html.erb +14 -0
  123. data/app/views/admin/ip_addresses/_nav_item.html.erb +6 -0
  124. data/app/views/admin/ip_addresses/entity/_in_list.html.erb +6 -0
  125. data/app/views/admin/ip_addresses/index.html.erb +13 -0
  126. data/app/views/admin/unauthorized.html.erb +19 -0
  127. data/app/views/authentication/_form.html.erb +40 -0
  128. data/app/views/authentication/failed.js.erb +3 -0
  129. data/app/views/authentication/new.html.erb +21 -0
  130. data/app/views/index/index.html.erb +0 -0
  131. data/app/views/layouts/admin.html.erb +23 -0
  132. data/app/views/layouts/admin/_breadcrumbs.html.erb +8 -0
  133. data/app/views/layouts/admin/_footer.html.erb +10 -0
  134. data/app/views/layouts/admin/_header.html.erb +18 -0
  135. data/app/views/layouts/admin/header/_logo.html.erb +3 -0
  136. data/app/views/layouts/application/_footer.html.erb +8 -0
  137. data/app/views/layouts/application/_header.html.erb +9 -0
  138. data/app/views/layouts/application/header/_authentication.html.erb +13 -0
  139. data/app/views/my/index/index.html.erb +0 -0
  140. data/app/views/my/profiles/closed.html.erb +12 -0
  141. data/app/views/my/profiles/new.html.erb +17 -0
  142. data/app/views/my/profiles/new/_form.html.erb +147 -0
  143. data/app/views/shared/_breadcrumbs.html.erb +8 -0
  144. data/app/views/shared/_cookie_notification.html.erb +4 -0
  145. data/app/views/shared/_flash_messages.html.erb +7 -0
  146. data/app/views/shared/_meta_texts.html.erb +31 -0
  147. data/app/views/shared/_nothing_found.html.erb +1 -0
  148. data/app/views/shared/_pagination.jbuilder +15 -0
  149. data/app/views/shared/admin/_list.html.erb +19 -0
  150. data/app/views/shared/admin/_list_with_priority.html.erb +19 -0
  151. data/app/views/shared/admin/_toggleable.html.erb +8 -0
  152. data/app/views/shared/entity/_list_of_errors.html.erb +7 -0
  153. data/app/views/shared/forms/errors.js.erb +5 -0
  154. data/config/initializers/carrierwave.rb +27 -0
  155. data/config/initializers/pluralization.rb +2 -0
  156. data/config/locales/biovision-ru.yml +90 -0
  157. data/config/locales/components-ru.yml +81 -0
  158. data/config/locales/track-ru.yml +40 -0
  159. data/config/locales/users-ru.yml +130 -0
  160. data/config/routes.rb +75 -0
  161. data/db/migrate/20191228000000_create_biovision_components.rb +72 -0
  162. data/db/migrate/20200224000000_create_track_component.rb +59 -0
  163. data/db/migrate/20200224000010_create_users_component.rb +189 -0
  164. data/db/migrate/20200404000000_create_simple_images.rb +54 -0
  165. data/lib/biovision.rb +9 -0
  166. data/lib/biovision/base_methods.rb +167 -0
  167. data/lib/biovision/engine.rb +40 -0
  168. data/lib/biovision/version.rb +5 -0
  169. data/lib/tasks/biovision_tasks.rake +4 -0
  170. metadata +392 -0
@@ -0,0 +1,2 @@
1
+ class My::RecoveriesController < ApplicationController
2
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Helper methods for component handling
4
+ module BiovisionComponentsHelper
5
+ # @param [BiovisionComponent] entity
6
+ # @param [String] text
7
+ # @param [Hash] options
8
+ def admin_biovision_component_link(entity, text = nil, options = {})
9
+ if text.nil?
10
+ text = t("biovision.components.#{entity.slug}.name", default: entity.slug)
11
+ end
12
+ link_to(text, admin_component_path(slug: entity.slug), options)
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Helpers for Users component
4
+ module UsersHelper
5
+ # @param [User] entity
6
+ def user_image_tiny(entity)
7
+ return image_tag('biovision/placeholders/user.svg', alt: '') if entity.nil?
8
+
9
+ image_tag(entity.image.tiny.url, alt: '')
10
+ end
11
+ end
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ # Base biovision component
6
+ class BaseComponent
7
+ extend ComponentSettings
8
+
9
+ attr_reader :component, :slug, :name, :user, :user_link
10
+
11
+ # @param [BiovisionComponent] component
12
+ # @param [User] user
13
+ def initialize(component, user = nil)
14
+ @component = component
15
+ @slug = component&.slug || 'base'
16
+ self.user = user
17
+
18
+ @name = I18n.t("biovision.components.#{@slug}.name", default: @slug)
19
+ end
20
+
21
+ # Receive component-specific handler by component slug
22
+ #
23
+ # @param [String|BiovisionComponent] input
24
+ # @param [User] user
25
+ # @return [BaseComponent]
26
+ def self.handler(input, user = nil)
27
+ type = input.is_a?(String) ? input : input&.slug
28
+ handler_class(type)[user]
29
+ end
30
+
31
+ def self.slug
32
+ to_s.demodulize.underscore.gsub('_component', '')
33
+ end
34
+
35
+ # Receive component-specific handler by class name for component.
36
+ #
37
+ # e.g.: Biovision::Components::UsersComponent[user]
38
+ #
39
+ # @param [User] user
40
+ def self.[](user = nil)
41
+ new(BiovisionComponent[slug], user)
42
+ end
43
+
44
+ # @param [String] slug
45
+ def self.handler_class(slug)
46
+ handler_name = "biovision/components/#{slug}_component".classify
47
+ handler_name.safe_constantize || BaseComponent
48
+ end
49
+
50
+ # Privilege names for using in biovision_component_user.data
51
+ def self.privilege_names
52
+ []
53
+ end
54
+
55
+ # @param [User] user
56
+ def self.privileged?(user)
57
+ return false if user.nil? || user.banned?
58
+ return true if user.super_user?
59
+
60
+ BiovisionComponentUser.owned_by(user).each do |link|
61
+ return true if link.administrator? || !link.data['privileges'].blank?
62
+ end
63
+
64
+ false
65
+ end
66
+
67
+ # @param [User] user
68
+ def user=(user)
69
+ @user = user
70
+
71
+ criteria = { biovision_component: @component, user: user }
72
+
73
+ @user_link = BiovisionComponentUser.find_by(criteria)
74
+ end
75
+
76
+ def user_link!(force_create = false)
77
+ if @user_link.nil?
78
+ criteria = { biovision_component: @component, user: user }
79
+ @user_link = BiovisionComponentUser.new(criteria)
80
+ @user_link.save if force_create
81
+ end
82
+
83
+ @user_link
84
+ end
85
+
86
+ def use_parameters?
87
+ false
88
+ end
89
+
90
+ def use_settings?
91
+ use_parameters? || @component.settings.any?
92
+ end
93
+
94
+ def administrator?
95
+ return false if user.nil?
96
+
97
+ user.super_user? || @user_link&.administrator?
98
+ end
99
+
100
+ # @param [String|Array] privileges
101
+ def allow?(*privileges)
102
+ return false if user.nil?
103
+ return true if administrator? || (component.nil? && privileges.blank?)
104
+ return false if @user_link.nil?
105
+
106
+ result = privileges.blank?
107
+ privileges.flatten.each { |slug| result |= privilege?(slug) }
108
+ result
109
+ end
110
+
111
+ # @param [String] privilege_name
112
+ def privilege?(privilege_name)
113
+ privilege_handler.privilege?(privilege_name)
114
+ end
115
+
116
+ # @param [Hash] data
117
+ def settings=(data)
118
+ @component.settings.merge!(self.class.normalize_settings(data))
119
+ @component.save!
120
+ end
121
+
122
+ def settings
123
+ @component.settings
124
+ end
125
+
126
+ # Receive parameter value with default
127
+ #
128
+ # Returns value of component's parameter or default value
129
+ # when it's not found
130
+ #
131
+ # @param [String] key
132
+ # @param [String] default
133
+ # @return [String]
134
+ def receive(key, default = '')
135
+ @component.get(key, default)
136
+ end
137
+
138
+ # Receive parameter value or nil
139
+ #
140
+ # Returns value of component's parameter of nil when it's not found
141
+ #
142
+ # @param [String] key
143
+ # @return [String]
144
+ def [](key)
145
+ @component.get(key)
146
+ end
147
+
148
+ # Set parameter
149
+ #
150
+ # @param [String] key
151
+ # @param [String] value
152
+ def []=(key, value)
153
+ @component[key] = value unless key.blank?
154
+ end
155
+
156
+ # @param [String] name
157
+ # @param [Integer] quantity
158
+ def register_metric(name, quantity = 1)
159
+ metric = Metric.find_by(name: name)
160
+ if metric.nil?
161
+ attributes = {
162
+ biovision_component: @component,
163
+ name: name,
164
+ incremental: !name.end_with?('.hit')
165
+ }
166
+ metric = Metric.create(attributes)
167
+ end
168
+
169
+ metric << quantity
170
+ end
171
+
172
+ def privilege_handler
173
+ @privilege_handler ||= PrivilegeHandler.new(self)
174
+ end
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ # Normalizing component settings
6
+ module ComponentSettings
7
+ def settings_flags
8
+ []
9
+ end
10
+
11
+ def settings_numbers
12
+ []
13
+ end
14
+
15
+ def settings_strings
16
+ []
17
+ end
18
+
19
+ # @param [Hash] data
20
+ def normalize_settings(data)
21
+ result = {}
22
+ settings_flags.each { |f| result[f] = data[f].to_i == 1 }
23
+ settings_numbers.each { |n| result[n] = data[n].to_i }
24
+ settings_strings.each { |s| result[s] = data[s].to_s }
25
+
26
+ result
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ # Handling user privileges in component
6
+ class PrivilegeHandler
7
+ attr_accessor :component
8
+
9
+ # @param [BaseComponent] component
10
+ def initialize(component)
11
+ @component = component
12
+ end
13
+
14
+ # @param [String|Symbol]
15
+ def privilege?(slug)
16
+ return false if @component.user_link.nil?
17
+
18
+ privileges = Array(@component.user_link.data['privileges'])
19
+ privileges.include?(slug)
20
+ end
21
+
22
+ def administrator!
23
+ return if @component.user.nil?
24
+
25
+ link = @component.user_link!
26
+ link.administrator = true
27
+ link.save
28
+ end
29
+
30
+ def not_administrator!
31
+ return if @component.user.nil? || @component.user_link.nil?
32
+
33
+ @component.user_link.update(administrator: false)
34
+ end
35
+
36
+ # @param [Array] new_privileges
37
+ def privileges=(new_privileges)
38
+ return if @component.user.nil?
39
+
40
+ link = @component.user_link!
41
+ link.data['privileges'] = Array(new_privileges).uniq
42
+ link.save
43
+ end
44
+
45
+ # @param [Hash] new_settings
46
+ def settings=(new_settings)
47
+ return if @component.user.nil?
48
+
49
+ link = @component.user_link!
50
+ link.data['settings'] = new_settings
51
+ link.save
52
+ end
53
+
54
+ # @param [String] slug
55
+ def add_privilege(slug)
56
+ return if @component.user.nil?
57
+
58
+ link = @component.user_link!
59
+ link.data['privileges'] ||= []
60
+ link.data['privileges'] += [slug.to_s]
61
+ link.data['privileges'].uniq!
62
+ link.save
63
+ end
64
+
65
+ # @param [String] slug
66
+ def remove_privilege(slug)
67
+ link = @component.user_link
68
+
69
+ return if link.nil?
70
+
71
+ link.data['privileges'] ||= []
72
+ link.data['privileges'] -= [slug.to_s]
73
+ link.save
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ # Component for tracking UA and IP
6
+ class TrackComponent < BaseComponent
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ module Users
6
+ # Authentication part of users component
7
+ module Authentication
8
+ def authenticate(password, track)
9
+ @password = password
10
+ @track = track
11
+ let_user_in?
12
+ end
13
+
14
+ protected
15
+
16
+ def let_user_in?
17
+ return false if user.nil? || user.banned?
18
+
19
+ too_many_attempts? ? (log_attempt && false) : try_password
20
+ end
21
+
22
+ def too_many_attempts?
23
+ timeout = settings['bounce_timeout'].to_i.abs.minutes.ago
24
+ limit = settings['bounce_limit'].to_i
25
+ LoginAttempt.owned_by(user).since(timeout).count > limit
26
+ end
27
+
28
+ def log_attempt
29
+ data = { password: @password }
30
+ LoginAttempt.owned_by(user).create(data.merge(@track))
31
+ end
32
+
33
+ def try_password
34
+ user.authenticate(@password) || (count_attempt && false)
35
+ end
36
+
37
+ def count_attempt
38
+ log_attempt
39
+ return unless too_many_attempts?
40
+
41
+ notifier = Biovision::Notifiers::UsersNotifier.new(user)
42
+ notifier.new_login_attempt(@track)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ module Users
6
+ # Handling user codes for different components
7
+ class CodeHandler
8
+ attr_accessor :code
9
+
10
+ # @param [Biovision::Components::BaseComponent] component
11
+ # @param [Code] code
12
+ def initialize(component, code = nil)
13
+ @component = component
14
+ self.code = code
15
+ end
16
+
17
+ def valid?
18
+ true
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ module Users
6
+ # Handling user profiles
7
+ class ProfileHandler
8
+ attr_accessor :user
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Biovision
4
+ module Components
5
+ module Users
6
+ # Handling user registration
7
+ class RegistrationHandler
8
+ # @param [Biovision::Components::UsersComponent] component
9
+ def initialize(component)
10
+ @component = component
11
+ end
12
+
13
+ def handle(parameters, code = nil)
14
+ @user = User.new(parameters)
15
+ @user.screen_name = @user.email if email_as_login?
16
+ @user.super_user = 1 if User.count < 1
17
+ @manager = CodeHandler.new(@component, code)
18
+
19
+ use_invites? ? use_code : persist_user
20
+ persist_user if @component.valid?(@user)
21
+
22
+ @user
23
+ end
24
+
25
+ def open?
26
+ @component.settings['registration_open']
27
+ end
28
+
29
+ def invite_only?
30
+ @component.settings['invite_only']
31
+ end
32
+
33
+ def use_invites?
34
+ @component.settings['use_invites'] || invite_only?
35
+ end
36
+
37
+ def confirm_email?
38
+ @component.settings['confirm_email']
39
+ end
40
+
41
+ def email_as_login?
42
+ @component.settings['email_as_login']
43
+ end
44
+
45
+ def require_email?
46
+ @component.settings['require_email'] || email_as_login?
47
+ end
48
+
49
+ protected
50
+
51
+ def persist_user
52
+ return unless @user.save
53
+
54
+ metric = Biovision::Components::UsersComponent::METRIC_NEW_USER
55
+ @component.register_metric(metric)
56
+
57
+ # handle_codes
58
+ end
59
+
60
+ # Check invitation code and persist user if it's valid
61
+ def use_code
62
+ if @manager.valid? || (@manager.code.nil? && !invite_only?)
63
+ persist_user
64
+ else
65
+ error = I18n.t('biovision.components.users.messages.invalid_code')
66
+
67
+ # Add "invalid code" error to other model errors, if any
68
+ @user.valid?
69
+ @user.errors.add(:code, error)
70
+ end
71
+ end
72
+
73
+ def handle_codes
74
+ if confirm_email?
75
+ code = CodeManager::Confirmation.code_for_user(@user)
76
+ CodeSender.email(code.id).deliver_later
77
+ end
78
+
79
+ return unless use_invites?
80
+
81
+ @manager.activate(@user) if @manager.valid?
82
+ create_invitations(settings['invite_count'].to_i)
83
+ end
84
+
85
+ # @param [Integer] quantity
86
+ def create_invitations(quantity = 1)
87
+ return unless quantity.positive?
88
+
89
+ parameters = {
90
+ code_type: CodeManager::Invitation.code_type,
91
+ user: @user,
92
+ quantity: quantity
93
+ }
94
+ Code.create(parameters)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end