Class: Replyr::ReplyAddress

Inherits:
Object
  • Object
show all
Defined in:
lib/replyr/reply_address.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, user) ⇒ ReplyAddress

Create a new reply address from a given user and model



9
10
11
12
# File 'lib/replyr/reply_address.rb', line 9

def initialize(model, user)
  @model = model
  @user = user
end

Instance Attribute Details

#modelObject

Returns the value of attribute model.



5
6
7
# File 'lib/replyr/reply_address.rb', line 5

def model
  @model
end

#userObject

Returns the value of attribute user.



5
6
7
# File 'lib/replyr/reply_address.rb', line 5

def user
  @user
end

Class Method Details

.class_from_normalized_model_name(model_name) ⇒ Object

Converts a normalized model_name back to a real model name and returns the class



89
90
91
# File 'lib/replyr/reply_address.rb', line 89

def self.class_from_normalized_model_name(model_name)
  model_name.gsub("+", "/").classify.constantize
end

.get_parsed_address(address) ⇒ Object

Split the reply email address. It has the following format: reply-comment-12-56-01ce26dc69094af9246ea7e7ce9970aff2b81cc9@reply.example.com



46
47
48
49
50
51
52
53
54
# File 'lib/replyr/reply_address.rb', line 46

def self.get_parsed_address(address)
  parsed = Mailman::Route::StringMatcher.new(Replyr.address_pattern).match(address)

  if parsed.nil?
    raise ArgumentError, "Malformed reply email address."
  else
    parsed.first # return Hash part
  end
end

.new_from_address(address) ⇒ Object

Create a reply address from a given address string Checks for validity of address and raises an ArgumentError if it’s invalid.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/replyr/reply_address.rb', line 18

def self.new_from_address(address)
  parts = get_parsed_address(address)

  model_class = class_from_normalized_model_name(parts[:model_name])
  model = model_class.find(parts[:model_id])
  user = Replyr.config.user_class.find(parts[:user_id])

  address = new(model, user)
  address.ensure_valid_token!(parts[:token])
  address
rescue
  Replyr.logger.warn "Reply email address invalid."
  nil
end

Instance Method Details

#addressObject Also known as: to_s

Returns the address string (e.g reply-comment-12-56-01ce26dc69094af9246ea7e7ce9970aff2b81cc9@reply.example.com)



103
104
105
106
107
108
109
110
# File 'lib/replyr/reply_address.rb', line 103

def address
  user_id = id_from_model(@user)
  model_id = id_from_model(@model)
  model_name = normalized_model_name(@model)

  local_part = [Replyr.config.prefix, model_name, model_id, user_id, token].join("-")
  "#{local_part}@#{Replyr.config.host}"
end

#ensure_valid_token!(token) ⇒ Object

Raises:

  • (RuntimeError)


39
40
41
# File 'lib/replyr/reply_address.rb', line 39

def ensure_valid_token!(token)
  raise(RuntimeError, "Token invalid.") unless token_valid?(token)
end

#id_from_model(object) ⇒ Object

Returns the ID of an AR object. Uses primary key to find out the correct field



96
97
98
# File 'lib/replyr/reply_address.rb', line 96

def id_from_model(object)
  object.send(object.class.primary_key)
end

#normalized_model_name(model) ⇒ Object

Model name by be namespaced (e.g. MyApp::Comment) For the reply email address the model name will be converted to “my_app/comment”. Then the slash “/” will be replaced with a plus sign “+”, because slashes should not be used email addresses.



82
83
84
# File 'lib/replyr/reply_address.rb', line 82

def normalized_model_name(model)
  model.class.name.tableize.singularize.gsub("/", "+")
end

#tokenObject

Returs the token from this address



58
59
60
# File 'lib/replyr/reply_address.rb', line 58

def token
  token_from_user_and_model(@user, @model)
end

#token_from_user_and_model(user, model) ⇒ Object

Creates a token from the passed user and model objects Uses the configured secret as a salt



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/replyr/reply_address.rb', line 65

def token_from_user_and_model(user, model)
  user_id = id_from_model(user)
  model_id = id_from_model(model)
  model_name = normalized_model_name(model)

  OpenSSL::HMAC.hexdigest(
    OpenSSL::Digest.new('sha1'),
    Replyr.config.secret,
    "#{user_id}-#{model_name}-#{model_id}"
  )
end

#token_valid?(token) ⇒ Boolean

Check if a given token is valid

Returns:

  • (Boolean)


35
36
37
# File 'lib/replyr/reply_address.rb', line 35

def token_valid?(token)
  token == self.token
end