Class: Decidim::OnboardingManager

Inherits:
Object
  • Object
show all
Defined in:
decidim-core/app/services/decidim/onboarding_manager.rb

Overview

This class is used to manage the onboarding funnel for users that intended to perform an action in the platform but it requires some verification steps to be completed.

The flow is as follows:

  1. A visitor (logged out) tries to perform an action that requires to be logged in

  2. The intended action is stored in a cookie (onboarding key)

  3. The visitor logs in and the onboarding cookie data is merged into the User#extended_data column.

  4. After logging in, the user is redirected to the onboarding pending authorizations page if there is any pending action stored in the User#extended_data column

  5. The user completes the required authorizations

  6. When the onboarding authorizations page detects that all the verification steps have been completed, it will remove the pending action from the User#extended_data column and redirect the user to the intended action.

Constant Summary collapse

DATA_KEY =

The same key is set in onboarding_pending_action js file to manage the onboarding data in the cookie

"onboarding"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user) ⇒ OnboardingManager

Returns a new instance of OnboardingManager.



27
28
29
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 27

def initialize(user)
  @user = user
end

Instance Attribute Details

#userObject (readonly)

Returns the value of attribute user.



25
26
27
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 25

def user
  @user
end

Instance Method Details

#actionObject

Returns the action to be performed.

Returns a string



45
46
47
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 45

def action
  onboarding_action
end

#action_authorized_resourcesObject

Returns a hash which can be passed to action_authorized_to helper method to determine the permissions status of the action

Returns a Hash



146
147
148
149
150
151
152
153
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 146

def action_authorized_resources
  return {} unless valid?

  {
    resource: model,
    permissions_holder: onboarding_permissions_holder.presence && permissions_holder
  }
end

#action_textObject

Returns the translation of the action to be performed if translation is found, otherwise the untranslated literal action key

Returns a string



53
54
55
56
57
58
59
60
61
62
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 53

def action_text
  @action_text ||= if component && I18n.exists?("#{component.manifest.name}.actions.#{action}", scope: "decidim.components")
                     I18n.t("#{component.manifest.name}.actions.#{action}", scope: "decidim.components")
                   elsif permissions_holder.respond_to?(:resource_manifest) &&
                         I18n.exists?("#{permissions_holder.resource_manifest.name}.actions.#{action}", scope: "decidim.resources")
                     I18n.t("#{permissions_holder.resource_manifest.name}.actions.#{action}", scope: "decidim.resources")
                   else
                     action
                   end
end

#authorization_pathObject



174
175
176
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 174

def authorization_path
  @authorization_path ||= onboarding_data["authorization_path"].presence
end

#available_authorization_selection_page?Boolean

This method is used to determine if an ephemeral user has an onboarding page to be redirected or only an authorization is required to complete the verification

Returns a Boolean

Returns:

  • (Boolean)


196
197
198
199
200
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 196

def available_authorization_selection_page?
  return true unless valid? && ephemeral?

  authorization_handlers.count > 1
end

#component_pathObject



168
169
170
171
172
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 168

def component_path
  return if component.blank?

  EngineRouter.main_proxy(component).root_path
end

#expired?Boolean

Returns:

  • (Boolean)


178
179
180
181
182
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 178

def expired?
  return unless ephemeral?

  session_duration > Decidim.config.expire_session_after.to_i
end

#filter_authorizations(authorizations) ⇒ Object

Filters the given authorizations that are required for the onboarding process.

authorizations - An array of Decidim::Authorization objects

Returns an array of Decidim::Authorization objects



129
130
131
132
133
134
135
136
137
138
139
140
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 129

def filter_authorizations(authorizations)
  filtered_authorizations = authorizations.select { |authorization| authorization_handlers.include?(authorization.name) }

  # By calling authorize on each authorization the path generated for each
  # one will include the specific options of the action if available
  filtered_authorizations.each do |authorization|
    next unless authorization.is_a? Decidim::Verifications::Adapter

    authorization.authorize(nil, permissions.dig("authorization_handlers", authorization.name, "options") || {}, model, permissions_holder)
  end
  filtered_authorizations
end

#finished_redirect_pathObject

Returns the path to redirect after finishing the verification process. The path can be obtained from the user onboarding redirect_path data or if a resource is present using a ResourceLocatorPresenter

Returns a String



160
161
162
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 160

def finished_redirect_path
  @finished_redirect_path ||= onboarding_data["redirect_path"].presence || model_path
end

#finished_verifications?(authorization_methods = active_authorization_methods) ⇒ Boolean

Checks if the user has completed all the required authorizations.

active_authorization_methods - A list of the active authorization methods for the user.

Returns a boolean

Returns:

  • (Boolean)


76
77
78
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 76

def finished_verifications?(authorization_methods = active_authorization_methods)
  (authorization_handlers - authorization_methods).empty?
end

#modelObject

Returns the model related to the action in the onboarding process.

Returns an ActiveRecord model



83
84
85
86
87
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 83

def model
  return if onboarding_model.blank?

  @model ||= GlobalID::Locator.locate(onboarding_model)
end

#model_nameObject

Returns the model name related to the action in the onboarding process.

Returns a string



102
103
104
105
106
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 102

def model_name
  return unless valid?

  @model_name ||= (model.presence || permissions_holder).class.model_name
end

#model_titleObject

Returns the resource title associated to the action. If the model is defined its title is used, if not the permissions holder title

Returns a translations Hash or a String



112
113
114
115
116
117
118
119
120
121
122
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 112

def model_title
  return unless valid?

  @model_title ||= begin
    resource = model.presence || permissions_holder

    method = [:title, :name].find { |m| resource.respond_to?(m) }

    resource.send(method) if method
  end
end

#pending_action?Boolean

Checks if there is any pending action for the user.

Returns a boolean

Returns:

  • (Boolean)


67
68
69
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 67

def pending_action?
  onboarding_data.present?
end

#permissions_holderObject

Returns the permissions_holder if present related to the action in the onboarding process.

Returns an ActiveRecord model



93
94
95
96
97
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 93

def permissions_holder
  return model if onboarding_permissions_holder.blank?

  @permissions_holder ||= GlobalID::Locator.locate(onboarding_permissions_holder)
end

#root_pathObject



164
165
166
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 164

def root_path
  component_path || Decidim::Core::Engine.routes.url_helpers.root_path
end

#session_durationObject

Time in seconds since the last login or creation of the user

Returns an Integer



187
188
189
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 187

def session_duration
  Time.current.to_i - (user. || user.created_at).to_i
end

#valid?Boolean

Checks if the onboarding data has an action and a model.

Returns a boolean

Returns:

  • (Boolean)


36
37
38
39
40
# File 'decidim-core/app/services/decidim/onboarding_manager.rb', line 36

def valid?
  return if action.blank?

  permissions_holder.present?
end