Module: TokenMaster::Core

Defined in:
lib/token_master/core.rb

Overview

TokenMaster::Core provides the core functionality of the TokenMaster gem. The Core module performs all of the logic of completing tokenable actions, and provides descriptive messages of the status or abilities of calls made.

Class Method Summary collapse

Class Method Details

.do_by_token!(klass, key, token, **params) ⇒ Object

Completes the tokenable action for a tokenable model instance using a token, setting tokenable_completed_at to the time at completion

Parameters:

  • klass (Object)

    the tokenable Class

  • key (String, Symbol)

    the tokenable action

  • token (String)

    the tokenable's token used to complete the action

  • params (Symbol=>String)

    keyword arguments required to complete the tokenable action

Returns:

  • (Object)

    tokenable Class instance

Raises:

  • (NotTokenableError)

    if the provided Class does not have the correct tokenable column

  • (TokenNotFoundError)

    if a tokenable instance cannot be found by the given token

  • (TokenCompletedError)

    if the tokenable action has already been completed, i.e., the tokenable instance has a timestamp in tokenable_completed_at

  • (TokenExpiredError)

    if the token is expired, i.e., the date is beyond the token's created_at plus token_lifetime

  • (MissingRequiredParamsError)

    if the params required by a tokenable are not provided



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/token_master/core.rb', line 20

def do_by_token!(klass, key, token, **params)
  check_manageable! klass, key
  token_column = { token_col(key) => token }
  model = klass.find_by(token_column)
  check_token_active! model, key
  check_params! key, params

  model.update!(
    params.merge(completed_at_col(key) => Time.now)
  )
  model
end

.force_tokenable!(model, key, **params) ⇒ Object

Completes the token action for a tokenable instance without a token, setting the tokenable_completed_at to the time at completion.
Usually implemented when you want to complete multiple tokenable actions at once, e.g., a user completes the invite action by setting up passwords, by default also completes the confirm action

Examples:

Force a Tokenable Action (Confirm)

user.force_confirm! =>
  <User id: 205, name: "John Smith", email: "[email protected]", confirm_token: nil, confirm_created_at: nil, confirm_sent_at: nil, confirm_completed_at: "2017-04-25 14:17:13">

Parameters:

  • model (Object)

    the tokenable model instance

  • key (String, Symbol)

    the tokenable action

  • params (Symbol=>String)

    keyword arguments required to complete the tokenable action

Returns:

  • (Object)

    tokenable Class instance

Raises:

  • (NotTokenableError)

    if the provided Class does not have the correct tokenable column

  • (MissingRequiredParamsError)

    if the params required by a tokenable are not provided



43
44
45
46
47
48
49
50
51
# File 'lib/token_master/core.rb', line 43

def force_tokenable!(model, key, **params)
  check_manageable! model.class, key
  check_params! key, params

  model.update!(
    params.merge(completed_at_col(key) => Time.now)
  )
  model
end

.send_instructions!(model, key) ⇒ Object

Accepts a block to pass on a generated token through a block, such as a mailer method, and sets tokenable_sent_at to the time the method is called

Examples:

Send Reset Instructions

user.send_reset_instruction! { user.send_email } =>
  <User id: 205, name: "John Smith", email: "[email protected]", reset_token: "3YcHkTJ7kXwV5wM", reset_created_at: 2017-04-25 14:20:54", reset_sent_at: "2017-04-25 14:22:42", reset_completed_at: nil>

Parameters:

  • model (Object)

    the tokenable model instance

  • key (String, Symbol)

    the tokenable action

Returns:

  • (Object)

    tokenable model instance

Raises:

  • (NotTokenableError)

    if the provided Class does not have the correct tokenable column

  • (TokenNotSetError)

    if the tokenable model instance does not have a token for the tokenable action

  • (TokenSentError)

    if this has already been called for the instance and tokenable action, i.e., tokenable_sent_at is not nil



84
85
86
87
88
89
90
91
92
93
# File 'lib/token_master/core.rb', line 84

def send_instructions!(model, key)
  check_manageable! model.class, key
  check_token_set! model, key
  check_instructions_sent! model, key

  yield if block_given?

  model.update(sent_at_col(key) => Time.now)
  model.save(validate: false)
end

.set_token!(model, key, token_length = nil) ⇒ String

Generates a tokenable action token, sets the token and the time of creation on the tokenable model instance

Parameters:

  • model (Object)

    the tokenable model instance

  • key (String, Symbol)

    the tokenable action

  • token_length (Integer) (defaults to: nil)

    the length of the generated token, method will use configuration token_length if not provided otherwise

Returns:

  • (String)

    token

Raises:

  • (NotTokenableError)

    if the provided Class does not have the correct tokenable column



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/token_master/core.rb', line 59

def set_token!(model, key, token_length = nil)
  check_manageable! model.class, key
  token_length ||= TokenMaster.config.get_token_length(key.to_sym)
  token = generate_token token_length

  model.update({
    token_col(key) => token,
    created_at_col(key) => Time.now,
    sent_at_col(key) => nil,
    completed_at_col(key) => nil
  })
  model.save(validate: false)
  token
end

.status(model, key) ⇒ String

Provides the status of the tokenable action, whether the action has been completed, the token has been sent, the token is expired, or the token has only been created

Parameters:

  • model (Object)

    the tokenable model instance

  • key (String, Symbol)

    the tokenable action

Returns:

  • (String)

    status of the tokenable action:

    • completed
    • sent
    • expired
    • created
    • no token

Raises:

  • (NotTokenableError)

    if the provided Class does not have the correct tokenable column



105
106
107
108
109
110
111
112
113
114
# File 'lib/token_master/core.rb', line 105

def status(model, key)
  check_manageable! model.class, key
  return 'completed' if completed?(model, key)
  return 'sent' if instructions_sent?(model, key)
  if token_set?(model, key)
    return 'expired' unless token_active?(model, key)
    return 'created'
  end
  'no token'
end