Class: Colossus::Faye::Extension

Inherits:
Object
  • Object
show all
Defined in:
lib/colossus/faye/extension.rb

Overview

Faye extension implementing all the presence, authorization, authentification and push logic.

Constant Summary collapse

VALID_STATUSES =
%w(disconnected away active).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(faye, colossus = Colossus.new) ⇒ Extension

Returns a new instance of Extension.



10
11
12
13
14
15
16
17
18
# File 'lib/colossus/faye/extension.rb', line 10

def initialize(faye, colossus = Colossus.new)
  @colossus = colossus
  @faye     = faye
  faye.add_extension(self)
  @faye_client = faye.get_client
  colossus_faye_extension = Colossus::WriterClient::FayeExtension.
    new(colossus.verifier.writer_token)
  faye_client.add_extension(colossus_faye_extension)
end

Instance Attribute Details

#colossusObject (readonly)

Returns the value of attribute colossus.



6
7
8
# File 'lib/colossus/faye/extension.rb', line 6

def colossus
  @colossus
end

#fayeObject (readonly)

Returns the value of attribute faye.



6
7
8
# File 'lib/colossus/faye/extension.rb', line 6

def faye
  @faye
end

#faye_clientObject (readonly)

Returns the value of attribute faye_client.



6
7
8
# File 'lib/colossus/faye/extension.rb', line 6

def faye_client
  @faye_client
end

Instance Method Details

#acceptable?(message) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
40
41
# File 'lib/colossus/faye/extension.rb', line 37

def acceptable?(message)
  message['ext'] &&
    (message['ext']['user_token'] ||
     message['ext']['writer_token'])
end

#handle_invalid_token(message) ⇒ Object



111
112
113
114
# File 'lib/colossus/faye/extension.rb', line 111

def handle_invalid_token(message)
  message['error'] = 'Invalid Token'
  message
end

#handle_presence_request(message) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/colossus/faye/extension.rb', line 83

def handle_presence_request(message)
  user_ids    = message['data'] && message['data']['user_ids']
  presence_id = message['channel'].partition('/presences/request/').last

  if user_ids && user_ids.is_a?(Array)
    statuses = colossus.get_multi(user_ids)
    message['data'].delete('user_ids')
    faye_client.publish("/presences/response/#{presence_id}", { 'statuses' => Hash[user_ids.zip(statuses)] })
    message
  elsif user_ids == nil
    statuses = colossus.get_all
    faye_client.publish("/presences/response/#{presence_id}", { 'statuses' => statuses })
    message
  else
    message.delete('data')
    message['error'] = 'Invalid user_ids data'
    message
  end
end

#handle_presence_response(message) ⇒ Object



103
104
105
# File 'lib/colossus/faye/extension.rb', line 103

def handle_presence_response(message)
  message
end

#handle_publish(message) ⇒ Object



107
108
109
# File 'lib/colossus/faye/extension.rb', line 107

def handle_publish(message)
  message
end

#handle_server_action(message) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/colossus/faye/extension.rb', line 57

def handle_server_action(message)
  token = message['ext'] && message['ext']['writer_token']

  unless token && colossus.verifier.verify_writer_token(token)
    message['error'] = 'Invalid Token'
    message.delete('data')
    return message
  end

  if message['channel'].start_with?('/meta/')
    message.delete('data')
    message
  elsif message['channel'].start_with?('/presences/request/')
    handle_presence_request(message)
  elsif message['channel'].start_with?('/presences/response/')
    handle_presence_response(message)
  elsif message['channel'].start_with?('/users/')
    handle_publish(message)
  else
    message['error'] = 'Unknown Action'
    message.delete('data')
  end

  message
end

#handle_set_status(message) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/colossus/faye/extension.rb', line 132

def handle_set_status(message)
  token   = message['ext']['user_token']
  user_id = message['channel'].partition('/users/').last
  status  = message['data'] && message['data']['status']

  if invalid_user_channel?(user_id)
    message['error'] = 'The only accepted channel_name is users/:user_id'
    return message
  end

  unless status && VALID_STATUSES.include?(status)
    message['error'] = 'Invalid Status'
    return message
  end

  unless colossus.verifier.verify_token(token, user_id)
    message['error'] = 'Invalid Token'
    return message
  end

  colossus.set(user_id, message['clientId'], status)

  message
end

#handle_subscribe(message) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/colossus/faye/extension.rb', line 116

def handle_subscribe(message)
  token   = message['ext']['user_token']
  user_id = message['subscription'].partition('/users/').last

  if invalid_user_channel?(user_id)
    message['error'] = 'The only accepted channel_name is users/:user_id'
    return message
  end

  unless colossus.verifier.verify_token(token, user_id)
    message['error'] = 'Invalid Token'
  end

  message
end

#handle_user_action(message) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/colossus/faye/extension.rb', line 43

def handle_user_action(message)
  if message['channel'] == '/meta/subscribe'
    handle_subscribe(message)
  elsif message['channel'].start_with?('/meta/')
    message
  elsif message['channel'].start_with?('/users/')
    handle_set_status(message)
  else
    message['error'] = 'Unknown Action'
  end

  message
end

#incoming(message, _request, callback) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/colossus/faye/extension.rb', line 20

def incoming(message, _request, callback)
  if !acceptable?(message)
    handle_invalid_token(message)
    message.delete('data')
    message.delete('ext')
  elsif message['ext']['user_token']
    handle_user_action(message)
    message.delete('data')
    message.delete('ext')
  elsif message['ext']['writer_token']
    handle_server_action(message)
    message.delete('ext')
  end

  callback.call(message)
end

#invalid_user_channel?(user_id) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/colossus/faye/extension.rb', line 157

def invalid_user_channel?(user_id)
  user_id.empty? || user_id.include?('*') || user_id.include?('/')
end