cent 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +7 -9
- data/README.md +165 -186
- data/cent.gemspec +14 -13
- data/lib/cent/client.rb +215 -227
- data/lib/cent/error.rb +41 -4
- data/lib/cent/notary.rb +68 -59
- data/lib/cent/version.rb +1 -1
- data/lib/cent.rb +1 -1
- metadata +27 -35
- data/.github/workflows/main.yml +0 -20
- data/.github/workflows/release.yml +0 -37
- data/.gitignore +0 -20
- data/.rspec +0 -3
- data/.rubocop.yml +0 -13
- data/lib/cent/http.rb +0 -47
data/lib/cent/notary.rb
CHANGED
|
@@ -6,84 +6,93 @@ require 'cent/error'
|
|
|
6
6
|
module Cent
|
|
7
7
|
# Cent::Notary
|
|
8
8
|
#
|
|
9
|
-
#
|
|
9
|
+
# Issues JWT tokens for Centrifugo client connections and channel subscriptions.
|
|
10
|
+
# Supports HMAC, RSA and ECDSA families of algorithms (HS256/384/512,
|
|
11
|
+
# RS256/384/512, ES256/384/512).
|
|
10
12
|
#
|
|
13
|
+
# @see https://centrifugal.dev/docs/server/authentication
|
|
14
|
+
# @see https://centrifugal.dev/docs/server/channel_token_auth
|
|
11
15
|
class Notary
|
|
12
|
-
# @param secret
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
# @
|
|
16
|
-
# notary = Cent::Notary.new(secret: 'secret')
|
|
17
|
-
#
|
|
16
|
+
# @param secret [String, OpenSSL::PKey::RSA, OpenSSL::PKey::EC] Secret key
|
|
17
|
+
# for the chosen algorithm. For HMAC pass the raw secret as a String. For
|
|
18
|
+
# RSA/ECDSA pass a PEM-loaded {OpenSSL::PKey::RSA} / {OpenSSL::PKey::EC}.
|
|
19
|
+
# @param algorithm [String] JWT algorithm, defaults to `HS256`.
|
|
18
20
|
def initialize(secret:, algorithm: 'HS256')
|
|
19
21
|
raise Error, 'Secret can not be nil' if secret.nil?
|
|
20
22
|
|
|
21
|
-
@secret
|
|
23
|
+
@secret = secret
|
|
22
24
|
@algorithm = algorithm
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
# @
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
# @param
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
# @param info
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
# @
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
# @return [String]
|
|
47
|
-
#
|
|
48
|
-
def issue_connection_token(sub:, info: nil, exp: nil)
|
|
27
|
+
# Issue a connection JWT used by clients when establishing a real-time
|
|
28
|
+
# connection to Centrifugo.
|
|
29
|
+
#
|
|
30
|
+
# @param sub [String] Standard JWT claim with the application user ID.
|
|
31
|
+
# Use an empty string for anonymous connections.
|
|
32
|
+
# @param exp [Integer] UNIX timestamp (seconds) when the token expires.
|
|
33
|
+
# @param iat [Integer] UNIX timestamp (seconds) when the token was issued.
|
|
34
|
+
# @param jti [String] Unique token identifier.
|
|
35
|
+
# @param aud [String] Token audience (matches `client.token.audience`).
|
|
36
|
+
# @param iss [String] Token issuer (matches `client.token.issuer`).
|
|
37
|
+
# @param info [Hash] Arbitrary public info attached to the connection.
|
|
38
|
+
# @param b64info [String] Base64-encoded `info` (for binary payloads).
|
|
39
|
+
# @param channels [Array<String>] Server-side subscription channel list.
|
|
40
|
+
# @param subs [Hash] Server-side subscriptions with per-channel options.
|
|
41
|
+
# @param meta [Hash] Server-only metadata attached to the connection.
|
|
42
|
+
# @param expire_at [Integer] Override connection expiration timestamp.
|
|
43
|
+
#
|
|
44
|
+
# @return [String] Encoded JWT.
|
|
45
|
+
def issue_connection_token(sub:, exp: nil, iat: nil, jti: nil, aud: nil, iss: nil,
|
|
46
|
+
info: nil, b64info: nil, channels: nil, subs: nil,
|
|
47
|
+
meta: nil, expire_at: nil)
|
|
49
48
|
payload = {
|
|
50
49
|
'sub' => sub,
|
|
50
|
+
'exp' => exp,
|
|
51
|
+
'iat' => iat,
|
|
52
|
+
'jti' => jti,
|
|
53
|
+
'aud' => aud,
|
|
54
|
+
'iss' => iss,
|
|
51
55
|
'info' => info,
|
|
52
|
-
'
|
|
56
|
+
'b64info' => b64info,
|
|
57
|
+
'channels' => channels,
|
|
58
|
+
'subs' => subs,
|
|
59
|
+
'meta' => meta,
|
|
60
|
+
'expire_at' => expire_at
|
|
53
61
|
}.compact
|
|
54
62
|
|
|
55
63
|
JWT.encode(payload, secret, algorithm)
|
|
56
64
|
end
|
|
57
65
|
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
# @
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
# @param
|
|
67
|
-
#
|
|
68
|
-
#
|
|
69
|
-
# @param
|
|
70
|
-
#
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
# @
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
#
|
|
77
|
-
# @see (https://centrifugal.github.io/centrifugo/server/private_channels/)
|
|
78
|
-
#
|
|
79
|
-
# @return [String]
|
|
80
|
-
#
|
|
81
|
-
def issue_channel_token(client:, channel:, info: nil, exp: nil)
|
|
66
|
+
# Issue a subscription JWT used by clients to authorize subscription to a
|
|
67
|
+
# channel that requires token authorization.
|
|
68
|
+
#
|
|
69
|
+
# @param sub [String] Application user ID (same meaning as in connection token).
|
|
70
|
+
# @param channel [String] Channel this subscription token is valid for.
|
|
71
|
+
# @param exp [Integer] UNIX timestamp (seconds) when the token expires.
|
|
72
|
+
# @param iat [Integer] UNIX timestamp (seconds) when the token was issued.
|
|
73
|
+
# @param jti [String] Unique token identifier.
|
|
74
|
+
# @param aud [String] Token audience.
|
|
75
|
+
# @param iss [String] Token issuer.
|
|
76
|
+
# @param info [Hash] Arbitrary channel info.
|
|
77
|
+
# @param b64info [String] Base64-encoded `info`.
|
|
78
|
+
# @param override [Hash] Per-subscription channel option overrides.
|
|
79
|
+
# @param expire_at [Integer] Override subscription expiration timestamp.
|
|
80
|
+
#
|
|
81
|
+
# @return [String] Encoded JWT.
|
|
82
|
+
def issue_channel_token(sub:, channel:, exp: nil, iat: nil, jti: nil, aud: nil, iss: nil,
|
|
83
|
+
info: nil, b64info: nil, override: nil, expire_at: nil)
|
|
82
84
|
payload = {
|
|
83
|
-
'
|
|
85
|
+
'sub' => sub,
|
|
84
86
|
'channel' => channel,
|
|
87
|
+
'exp' => exp,
|
|
88
|
+
'iat' => iat,
|
|
89
|
+
'jti' => jti,
|
|
90
|
+
'aud' => aud,
|
|
91
|
+
'iss' => iss,
|
|
85
92
|
'info' => info,
|
|
86
|
-
'
|
|
93
|
+
'b64info' => b64info,
|
|
94
|
+
'override' => override,
|
|
95
|
+
'expire_at' => expire_at
|
|
87
96
|
}.compact
|
|
88
97
|
|
|
89
98
|
JWT.encode(payload, secret, algorithm)
|
data/lib/cent/version.rb
CHANGED
data/lib/cent.rb
CHANGED
metadata
CHANGED
|
@@ -1,71 +1,65 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cent
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sergey Prikhodko
|
|
8
|
-
|
|
8
|
+
- Centrifugal Labs
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
20
|
-
- - "
|
|
19
|
+
version: '2.0'
|
|
20
|
+
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version:
|
|
22
|
+
version: '4'
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
|
-
- - "
|
|
27
|
+
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version:
|
|
30
|
-
- - "
|
|
29
|
+
version: '2.0'
|
|
30
|
+
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version:
|
|
32
|
+
version: '4'
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: jwt
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- - "
|
|
37
|
+
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version:
|
|
40
|
-
- - "
|
|
39
|
+
version: '2.2'
|
|
40
|
+
- - "<"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
|
-
version:
|
|
42
|
+
version: '4'
|
|
43
43
|
type: :runtime
|
|
44
44
|
prerelease: false
|
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
|
46
46
|
requirements:
|
|
47
|
-
- - "
|
|
47
|
+
- - ">="
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
|
-
version:
|
|
50
|
-
- - "
|
|
49
|
+
version: '2.2'
|
|
50
|
+
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
|
-
version:
|
|
52
|
+
version: '4'
|
|
53
53
|
description: |
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
`Client::Notary` is a simple JWT wrapper to generate authorization tokens for the frontend
|
|
54
|
+
Ruby client for Centrifugo server HTTP API. Provides Cent::Client to call
|
|
55
|
+
Centrifugo server methods (publish, broadcast, subscribe, presence, history, ...)
|
|
56
|
+
and Cent::Notary to issue JWT connection and subscription tokens.
|
|
58
57
|
email:
|
|
59
58
|
- prikha@gmail.com
|
|
60
59
|
executables: []
|
|
61
60
|
extensions: []
|
|
62
61
|
extra_rdoc_files: []
|
|
63
62
|
files:
|
|
64
|
-
- ".github/workflows/main.yml"
|
|
65
|
-
- ".github/workflows/release.yml"
|
|
66
|
-
- ".gitignore"
|
|
67
|
-
- ".rspec"
|
|
68
|
-
- ".rubocop.yml"
|
|
69
63
|
- CHANGELOG.md
|
|
70
64
|
- Gemfile
|
|
71
65
|
- LICENSE.txt
|
|
@@ -77,16 +71,15 @@ files:
|
|
|
77
71
|
- lib/cent.rb
|
|
78
72
|
- lib/cent/client.rb
|
|
79
73
|
- lib/cent/error.rb
|
|
80
|
-
- lib/cent/http.rb
|
|
81
74
|
- lib/cent/notary.rb
|
|
82
75
|
- lib/cent/version.rb
|
|
83
76
|
homepage: https://github.com/centrifugal/rubycent
|
|
84
77
|
licenses:
|
|
85
78
|
- MIT
|
|
86
79
|
metadata:
|
|
87
|
-
homepage_uri: https://github.com/centrifugal/rubycent
|
|
88
80
|
source_code_uri: https://github.com/centrifugal/rubycent
|
|
89
|
-
|
|
81
|
+
changelog_uri: https://github.com/centrifugal/rubycent/releases
|
|
82
|
+
bug_tracker_uri: https://github.com/centrifugal/rubycent/issues
|
|
90
83
|
rdoc_options: []
|
|
91
84
|
require_paths:
|
|
92
85
|
- lib
|
|
@@ -94,15 +87,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
94
87
|
requirements:
|
|
95
88
|
- - ">="
|
|
96
89
|
- !ruby/object:Gem::Version
|
|
97
|
-
version:
|
|
90
|
+
version: '3.0'
|
|
98
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
92
|
requirements:
|
|
100
93
|
- - ">="
|
|
101
94
|
- !ruby/object:Gem::Version
|
|
102
95
|
version: '0'
|
|
103
96
|
requirements: []
|
|
104
|
-
rubygems_version: 3.
|
|
105
|
-
signing_key:
|
|
97
|
+
rubygems_version: 3.6.9
|
|
106
98
|
specification_version: 4
|
|
107
|
-
summary: Centrifugo API
|
|
99
|
+
summary: Centrifugo server API client for Ruby
|
|
108
100
|
test_files: []
|
data/.github/workflows/main.yml
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
name: Ruby
|
|
2
|
-
|
|
3
|
-
on: [push,pull_request]
|
|
4
|
-
|
|
5
|
-
jobs:
|
|
6
|
-
build:
|
|
7
|
-
runs-on: ubuntu-latest
|
|
8
|
-
strategy:
|
|
9
|
-
matrix:
|
|
10
|
-
ruby-version: ['2.7', '3.3']
|
|
11
|
-
steps:
|
|
12
|
-
- uses: actions/checkout@v4
|
|
13
|
-
- name: Set up Ruby
|
|
14
|
-
uses: ruby/setup-ruby@v1
|
|
15
|
-
with:
|
|
16
|
-
ruby-version: ${{ matrix.ruby-version }}
|
|
17
|
-
- name: Run the default task
|
|
18
|
-
run: |
|
|
19
|
-
bundle install
|
|
20
|
-
bundle exec rake
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
name: Release Ruby Gem
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- 'v[0-9].[0-9]+.[0-9]+'
|
|
7
|
-
jobs:
|
|
8
|
-
build-and-release:
|
|
9
|
-
name: Release
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
permissions:
|
|
12
|
-
packages: write
|
|
13
|
-
contents: read
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout
|
|
17
|
-
uses: actions/checkout@v4
|
|
18
|
-
|
|
19
|
-
- name: Set up Ruby
|
|
20
|
-
uses: ruby/setup-ruby@v1
|
|
21
|
-
with:
|
|
22
|
-
ruby-version: 3.3.0
|
|
23
|
-
|
|
24
|
-
- name: Bundle install
|
|
25
|
-
run: |
|
|
26
|
-
bundle install
|
|
27
|
-
|
|
28
|
-
- name: Publish to RubyGems
|
|
29
|
-
run: |
|
|
30
|
-
mkdir -p $HOME/.gem
|
|
31
|
-
touch $HOME/.gem/credentials
|
|
32
|
-
chmod 0600 $HOME/.gem/credentials
|
|
33
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
34
|
-
gem build *.gemspec
|
|
35
|
-
gem push *.gem
|
|
36
|
-
env:
|
|
37
|
-
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_API_KEY}}"
|
data/.gitignore
DELETED
data/.rspec
DELETED
data/.rubocop.yml
DELETED
data/lib/cent/http.rb
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'cent/error'
|
|
4
|
-
|
|
5
|
-
module Cent
|
|
6
|
-
# Cent::ResponseError
|
|
7
|
-
#
|
|
8
|
-
# Raised when response from Centrifugo contains any error as result of API command execution.
|
|
9
|
-
#
|
|
10
|
-
class ResponseError < Error
|
|
11
|
-
attr_reader :code
|
|
12
|
-
|
|
13
|
-
def initialize(code:, message:)
|
|
14
|
-
@code = code
|
|
15
|
-
super(message)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
# Cent::HTTP
|
|
20
|
-
#
|
|
21
|
-
# Holds request call and response handling logic
|
|
22
|
-
#
|
|
23
|
-
class HTTP
|
|
24
|
-
attr_reader :connection
|
|
25
|
-
|
|
26
|
-
# @param connection [Faraday::Connection] HTTP Connection object
|
|
27
|
-
#
|
|
28
|
-
def initialize(connection:)
|
|
29
|
-
@connection = connection
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# Perform POST request to centrifugo API
|
|
33
|
-
# @param body [Hash] Request body(non serialized)
|
|
34
|
-
#
|
|
35
|
-
# @raise [Cent::ResponseError]
|
|
36
|
-
#
|
|
37
|
-
# @return [Hash] Parsed response body
|
|
38
|
-
#
|
|
39
|
-
def post(body: nil)
|
|
40
|
-
response = connection.post(nil, body)
|
|
41
|
-
|
|
42
|
-
raise ResponseError.new(**response.body['error'].transform_keys(&:to_sym)) if response.body.key?('error')
|
|
43
|
-
|
|
44
|
-
response.body
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|