philote 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d557198f8bbe6a2c9e3dbdbbe09883bd10823ef0
4
- data.tar.gz: 72e9eb3d90d5f08b330a8cfe135d2d4a6a22a05b
3
+ metadata.gz: 83d0f685634d24a1933c7b4f1b24f8f2522b75de
4
+ data.tar.gz: b35d3bbfa5239de1afdf3494ba7568fa8be9fadf
5
5
  SHA512:
6
- metadata.gz: 1f8e06dc95017cf9d64340e5e893e972a378434ea4ba477019b4ff12d8bf97e4605cf3b007a992d6ca379104d6521984a79aed70ab172fbee80889f4c79bf322
7
- data.tar.gz: cdd9c5a0156dd88c5912fa777bd0d0d0804c6191c91a8bc977d725e148df5505b8ef835b69ccbad933b35e175c3655b9d9d1df11d3b2694ed6d0db4c26f836b5
6
+ metadata.gz: 981e71e46ee073dea63e67f1d5d0dca72ef3afcd8c46a1ca08561ecf426f1ea59be43c12bf9ef193195b282892082b72fba8e88a8b5eb0189b499e90e83d7d47
7
+ data.tar.gz: 2a0dd3137c8da5ea54e9331350deaa8701bd3ab25ea8f030dff9b9857dd3a19d04c8e6f7af18a29627c83d179dbe7b168366fa3166f0f9bdb918b811c9748b87
@@ -1,7 +1,7 @@
1
1
  # vim: ft=sh
2
- export GEM_HOME="$PWD/.deps"
2
+ export GEM_HOME="$PWD/.dependencies"
3
3
  export GEM_BIN="$GEM_HOME/bin"
4
+ export RUBYLIB="$PWD/lib":"$RUBYLIB"
4
5
  export PATH="$GEM_BIN":"$PATH"
5
6
 
6
- export DISC_CONCURRENCY=2
7
- export QUEUES="test_medium"
7
+ export REDIS_TEST_URL="redis://localhost:6379/9"
data/.gems CHANGED
@@ -1,2 +1,3 @@
1
1
  cutest:1.2.2
2
2
  redic:1.5.0
3
+ byebug:9.0.5
data/.gitignore CHANGED
@@ -1,3 +1,2 @@
1
1
  *.gem
2
- nodes.conf
3
- .deps
2
+ .dependencies
@@ -0,0 +1,73 @@
1
+ # philote.rb
2
+
3
+ This is a helper library for [Philote](https://github.com/13Floor/philote), a [Redis](http://redis.io)-powered websockets server.
4
+
5
+ You don't really need this library: philote takes configuration from the Redis database it uses, so you are perfectly capable of create philote access tokens yourself and storing them in redis, however, this library makes it easier for you to do so.
6
+
7
+ ## Early Stages
8
+
9
+ This library is still on very early stages, it does something extremely simple so bugs are generally not expected, but functionality like subscribing to channels and reacting to incoming messages is not yet implemented, if you use Philote for anything and feel like contributing that would be a great way to do it. :)
10
+
11
+
12
+ ## Usage
13
+
14
+ ### Redis Connection
15
+
16
+ By default, Philote connects to Redis using the `REDIS_URL` environment variable, if you want to connect in a different way you can specify the redis client in code when you initialize your application.
17
+
18
+ ```ruby
19
+
20
+ require 'redic'
21
+ require 'philote'
22
+
23
+ Philote.redis = Redic.new('redis://localhost:6379')
24
+ ```
25
+
26
+ ### Access Keys
27
+
28
+ In order to connect to Philote, a websocket client will need an [access key](https://github.com/pote/philote#access-keys), you can create them via `Philote::AccessKey#create`, here's the method signature:
29
+
30
+ ```ruby
31
+ class AccessKey
32
+ # read:
33
+ # an array of channel names the key user will be subscribed to.
34
+ #
35
+ # write:
36
+ # an array of channel names the key user will be able to write to.
37
+ #
38
+ # allowed_uses:
39
+ # the ammount of times a new websocket client will be able to authenticate
40
+ # using this access key.
41
+ #
42
+ # uses:
43
+ # the ammount of times a new websocket client has authenticated using this
44
+ # access key.
45
+ #
46
+ # token:
47
+ # the redis identifier.
48
+ #
49
+ def initialize(read: [], write: [], allowed_uses: 1, uses: 0, token: nil)
50
+ # ...
51
+ end
52
+ end
53
+ ```
54
+
55
+ After you create an access key, a client will be able to authenticate in the Philote server running on the same Redis instance, `Philote::AccessKey#token` will contain the identifier, on a regular browser javascript use case you'll render your view with access to this token.
56
+
57
+ ### Publishing Messages
58
+
59
+ As Philote uses Redis PUB/SUB under the hood, as long as your Ruby code has access to the same Redis instance you can publish messages to the websocket channels simply by publishing those messages to Redis, this library provides a helper method to do that.
60
+
61
+ ```ruby
62
+ Philote.publish('channel-name', 'data')
63
+ ```
64
+
65
+ ## Run the test suite
66
+
67
+ Here's how to set up the local/test environment:
68
+
69
+ ```bash
70
+ $ git clone git@github.com:pote/philote-rb.git && cd philote-rb
71
+ $ source .env.sample # Make sure to review the settings, as the REDIS_TEST_URL gets flushed when running the test suite.
72
+ $ make test
73
+ ```
@@ -7,10 +7,118 @@ module Philote
7
7
  @redis ||= Redic.new
8
8
  end
9
9
 
10
- def self.redis=(redis)
11
- @redis = redis
10
+ def self.redis=(client)
11
+ @redis = client
12
12
  end
13
+
14
+ def self.prefix
15
+ @prefix ||= 'philote'
16
+ end
17
+
18
+ def self.prefix=(p)
19
+ @prefix = p
20
+ end
21
+
22
+ def self.publish(channel, data)
23
+ redis.call('PUBLISH', channel, data)
24
+ end
25
+
26
+ class AccessKey
27
+ attr_accessor :read, :write, :allowed_uses, :uses, :token
28
+
29
+
30
+ # read:
31
+ # an array of channel names the key user will be subscribed to.
32
+ #
33
+ # write:
34
+ # an array of channel names the key user will be able to write to.
35
+ #
36
+ # allowed_uses:
37
+ # the ammount of times a new websocket client will be able to authenticate
38
+ # using this access key.
39
+ #
40
+ # uses:
41
+ # the ammount of times a new websocket client has authenticated using this
42
+ # access key.
43
+ #
44
+ # token:
45
+ # the redis identifier.
46
+ #
47
+ def initialize(read: [], write: [], allowed_uses: 1, uses: 0, token: nil)
48
+ @token = token || SecureRandom.urlsafe_base64
49
+ @read = read
50
+ @write = write
51
+ @allowed_uses = allowed_uses
52
+ @uses = uses
53
+
54
+ self
55
+ end
56
+
57
+ def to_json
58
+ self.to_h.to_json
59
+ end
60
+
61
+ def save
62
+ Philote.redis.call('SET', "#{ Philote.prefix }:access_key:#{ token }", self.to_json)
63
+ end
64
+
65
+ def to_h
66
+ {
67
+ read: read,
68
+ write: write,
69
+ allowed_uses: allowed_uses,
70
+ uses: uses
71
+ }
72
+ end
73
+ alias_method :to_hash, :to_h
74
+
75
+
76
+ def self.create(**args)
77
+ key = self.new(**args)
78
+ key.save
79
+
80
+ return key
81
+ end
82
+
83
+ def self.load!(token)
84
+ raw_key = Philote.redis.call('GET', "philote:access_key:#{ token }")
85
+ raise NonExistantAccessKey if raw_key.nil?
86
+
87
+ begin
88
+ parsed_key_attributes = JSON.parse(raw_key)
89
+ rescue => exception
90
+ raise UnparsableAccessKeyData.new(exception)
91
+ end
92
+
93
+ begin
94
+ key_attributes = {
95
+ read: parsed_key_attributes.fetch('read'),
96
+ write: parsed_key_attributes.fetch('write'),
97
+ allowed_uses: parsed_key_attributes.fetch('allowed_uses'),
98
+ uses: parsed_key_attributes.fetch('uses'),
99
+ token: token
100
+ }
101
+ rescue => exception
102
+ raise InsufficientAccessKeyData.new(exception)
103
+ end
104
+
105
+ return self.new(key_attributes)
106
+ end
107
+
108
+ def self.load(token)
109
+ begin
110
+ key = self.load!(token)
111
+ return key
112
+ rescue => exception
113
+ return nil
114
+ end
115
+ end
116
+ end
117
+
118
+ class Error < StandardError; end
119
+ class NonExistantAccessKey < Error; end
120
+ class UnparsableAccessKeyData < Error; end
121
+ class InsufficientAccessKeyData < Error; end
13
122
  end
14
123
 
15
124
  require_relative 'philote/version'
16
- require_relative 'philote/admin'
@@ -1,3 +1,3 @@
1
1
  module Philote
2
- VERSION = "0.1.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -0,0 +1,45 @@
1
+ require 'cutest'
2
+ require 'philote'
3
+
4
+
5
+ setup {
6
+ Philote.redis = Redic.new(ENV.fetch('REDIS_TEST_URL'))
7
+ }
8
+
9
+ at_exit {
10
+ Redic.new(ENV.fetch('REDIS_TEST_URL')).call('FLUSHDB')
11
+ }
12
+
13
+ test 'client should have a functioning redis connection' do
14
+ assert_equal 'PONG', Philote.redis.call('PING')
15
+ end
16
+
17
+ test 'creating an access key creates a token with sensible defaults' do
18
+ access_key = Philote::AccessKey.create
19
+
20
+ assert_equal [], access_key.read
21
+ assert_equal [], access_key.write
22
+ assert_equal 1, access_key.allowed_uses
23
+ assert_equal 0, access_key.uses
24
+ assert !access_key.token.nil?
25
+ end
26
+
27
+ test 'loading an access key works' do
28
+ access_key = Philote::AccessKey.create(
29
+ read: %w(mychannel), write: %w(mychannel), allowed_uses: 5, uses: 3)
30
+
31
+ assert_equal %w(mychannel), access_key.read
32
+ assert_equal %w(mychannel), access_key.write
33
+ assert_equal 5, access_key.allowed_uses
34
+ assert_equal 3, access_key.uses
35
+
36
+ access_key = Philote::AccessKey.load(access_key.token)
37
+
38
+ assert !access_key.nil?
39
+ assert access_key.is_a?(Philote::AccessKey)
40
+ assert_equal %w(mychannel), access_key.read
41
+ assert_equal %w(mychannel), access_key.write
42
+ assert_equal 5, access_key.allowed_uses
43
+ assert_equal 3, access_key.uses
44
+ assert !access_key.token.nil?
45
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philote
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pote
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-16 00:00:00.000000000 Z
11
+ date: 2016-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redic
@@ -37,10 +37,11 @@ files:
37
37
  - CONTRIBUTING.md
38
38
  - LICENSE
39
39
  - Makefile
40
+ - README.md
40
41
  - lib/philote.rb
41
- - lib/philote/admin.rb
42
42
  - lib/philote/version.rb
43
43
  - philote.gemspec
44
+ - test/access_key_test.rb
44
45
  homepage: https://github.com/pote/philote-rb
45
46
  licenses:
46
47
  - MIT
@@ -1,18 +0,0 @@
1
- module Philote::Admin
2
- def self.create_token(read: [], write: [], allowed_uses: 1)
3
- permissions = {
4
- read: read,
5
- write: write,
6
- allowed_uses: allowed_uses,
7
- uses: 0
8
- }
9
-
10
- token = SecureRandom.urlsafe_base64
11
-
12
- Philote.redis.call('SET', "philote:access_key:#{token}", permissions.to_json )
13
- end
14
-
15
- def self.publish(channel, message)
16
- Philote.redis.call('PUBLISH', channel, message )
17
- end
18
- end