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



86
87
88
# File 'lib/replyr/reply_address.rb', line 86

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



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

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
32
# 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)
  if address.token_valid?(parts[:token])
    address
  else
    Replyr.logger.warn "Reply email address invalid."
    nil
  end
end

Instance Method Details

#addressObject Also known as: to_s

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



100
101
102
103
104
105
106
107
# File 'lib/replyr/reply_address.rb', line 100

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

#id_from_model(object) ⇒ Object

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



93
94
95
# File 'lib/replyr/reply_address.rb', line 93

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.



79
80
81
# File 'lib/replyr/reply_address.rb', line 79

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

#tokenObject

Returs the token from this address



55
56
57
# File 'lib/replyr/reply_address.rb', line 55

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



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/replyr/reply_address.rb', line 62

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)


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

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