Class: Ribbon::Intercom::Service::Channel

Inherits:
Object
  • Object
show all
Includes:
BCrypt
Defined in:
lib/ribbon/intercom/service/channel.rb,
lib/ribbon/intercom/service/channel/stores.rb

Defined Under Namespace

Modules: Stores

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store, params = {}) ⇒ Channel

Returns a new instance of Channel.



18
19
20
21
22
23
# File 'lib/ribbon/intercom/service/channel.rb', line 18

def initialize(store, params={})
  @store = store
  @name = params[:name] or raise Errors::ChannelNameMissingError
  @token = params[:token]
  refresh(params)
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



11
12
13
# File 'lib/ribbon/intercom/service/channel.rb', line 11

def name
  @name
end

#secret_hash_crtObject (readonly)

Returns the value of attribute secret_hash_crt.



15
16
17
# File 'lib/ribbon/intercom/service/channel.rb', line 15

def secret_hash_crt
  @secret_hash_crt
end

#secret_hash_prvObject (readonly)

Returns the value of attribute secret_hash_prv.



16
17
18
# File 'lib/ribbon/intercom/service/channel.rb', line 16

def secret_hash_prv
  @secret_hash_prv
end

#signing_keysObject (readonly)

Returns the value of attribute signing_keys.



14
15
16
# File 'lib/ribbon/intercom/service/channel.rb', line 14

def signing_keys
  @signing_keys
end

#storeObject (readonly)

Returns the value of attribute store.



12
13
14
# File 'lib/ribbon/intercom/service/channel.rb', line 12

def store
  @store
end

#tokenObject (readonly)

Returns the value of attribute token.



13
14
15
# File 'lib/ribbon/intercom/service/channel.rb', line 13

def token
  @token
end

Instance Method Details

#==(other) ⇒ Object



110
111
112
113
114
115
116
117
118
# File 'lib/ribbon/intercom/service/channel.rb', line 110

def ==(other)
  other.is_a?(Channel) &&
    name == other.name &&
    store == other.store &&
    token == other.token &&
    secret_crt.to_s == other.secret_crt.to_s &&
    secret_prv.to_s == other.secret_prv.to_s &&
    permissions == other.permissions
end

#closeObject



106
107
108
# File 'lib/ribbon/intercom/service/channel.rb', line 106

def close
  store.delete(self)
end

#may(*args) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/ribbon/intercom/service/channel.rb', line 60

def may(*args)
  (@_allowed_to ||= Hash.new(false)).merge!(
    Hash[
      args.map { |perm| [perm.to_s, true] }
    ]
  ).keys.to_set
end

#may!(*args) ⇒ Object



68
69
70
# File 'lib/ribbon/intercom/service/channel.rb', line 68

def may!(*args)
  may(*args).tap { save }
end

#may?(*perms) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/ribbon/intercom/service/channel.rb', line 72

def may?(*perms)
  perms.all? { |perm| _may?(perm) }
end

#permissionsObject



76
77
78
# File 'lib/ribbon/intercom/service/channel.rb', line 76

def permissions
  @_allowed_to.keys.to_set
end

#refresh(params = {}) ⇒ Object

Refreshes the channel. To be called by the store after obtaining a lock.



27
28
29
30
31
32
33
34
# File 'lib/ribbon/intercom/service/channel.rb', line 27

def refresh(params={})
  @secret_hash_crt = params[:secret_hash_crt]
  @secret_hash_prv = params[:secret_hash_prv]
  @signing_keys = params[:signing_keys] || {}

  @_allowed_to = nil
  may(*params.fetch(:may, []))
end

#rotate_secretObject



36
37
38
39
40
41
# File 'lib/ribbon/intercom/service/channel.rb', line 36

def rotate_secret
  SecureRandom.hex(16).tap { |secret|
    @secret_hash_prv = secret_hash_crt
    @secret_hash_crt = Password.create(secret)
  }
end

#rotate_secret!Object



43
44
45
# File 'lib/ribbon/intercom/service/channel.rb', line 43

def rotate_secret!
  rotate_secret.tap { save }
end

#saveObject



96
97
98
99
100
101
102
103
104
# File 'lib/ribbon/intercom/service/channel.rb', line 96

def save
  # Loop until unique
  unless token
    loop { break unless store.token_exists?(@token = SecureRandom.hex(4)) }
  end

  _run_validations
  store.persist(self)
end

#secret_crtObject



84
85
86
# File 'lib/ribbon/intercom/service/channel.rb', line 84

def secret_crt
  @__secret_crt ||= _to_bcrypt_pw(secret_hash_crt)
end

#secret_prvObject



88
89
90
# File 'lib/ribbon/intercom/service/channel.rb', line 88

def secret_prv
  @__secret_prv ||= _to_bcrypt_pw(secret_hash_prv)
end

#sign(data) ⇒ Object



47
48
49
50
# File 'lib/ribbon/intercom/service/channel.rb', line 47

def sign(data)
  key_id, key = _signing_key
  "\x01" + [key_id].pack('N') + Utils::Signer.new(key).sign(data)
end

#valid_secret?(secret) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/ribbon/intercom/service/channel.rb', line 80

def valid_secret?(secret)
  !!secret && (secret_crt == secret || secret_prv == secret)
end

#verify(signed_data) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/ribbon/intercom/service/channel.rb', line 52

def verify(signed_data)
  key_id = signed_data.slice(1, 4).unpack('N').first

  if (key=_retrieve_signing_key(key_id))
    Utils::Signer.new(key).verify(signed_data[5..-1])
  end
end

#with_lock(&block) ⇒ Object



92
93
94
# File 'lib/ribbon/intercom/service/channel.rb', line 92

def with_lock(&block)
  store.with_lock(self, &block)
end