jwplayer-api-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a8e059510251aba539bab5f51b2fcbc3d9b85498
4
+ data.tar.gz: 8c9eece592fa5fd99af7cfd319f09fb6ecccc56d
5
+ SHA512:
6
+ metadata.gz: 7c8b185574284531005bd311b5efefab08ca3136550fa2dd689ed4250aa3b2129e644f17a8c37d66ddc39a5778372e71bf6c735d47afe323987637ec41176c82
7
+ data.tar.gz: 6677eff90b196e735326a6cffcc991d427b4d1b6d8b564bf751f2e071102092bf544882efe7e0f36dbc65cdfac5259c0131f6b07838a52dab1ff68fa548783c3
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.idea/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jwplayer-api-client.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 raphi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,108 @@
1
+ # JWPlayer::API::Client
2
+
3
+ This gem aims to easily sign JWPlayer Platform API URLs according to the documentation: https://developer.jwplayer.com/jw-platform/reference/v1/authentication.html
4
+ It is not intended to actually send the request but simply to generate the correctly signed URL. An example at the end of this documentation is provided though.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'jwplayer-api-client'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install jwplayer-api-client
21
+
22
+ ## Usage
23
+
24
+ To get started, instantiate a new client:
25
+
26
+ ```ruby
27
+ irb> client = JWPlayer::API::Client.new(key: 'y0c6CFQ5', secret: 'YZWQ1SfmpFYEfW9kiR1QerRF')
28
+ => #<JWPlayer::API::Client:0x007fb6909e0158 @options={:host=>"api.jwplatform.com", :scheme=>"https", :version=>:v1, :key=>"y0c6CFQ5", :secret=>"YZWQ1SfmpFYEfW9kiR1QerRF", :format=>:json}>
29
+ ```
30
+
31
+ If you have previously set `JWPLAYER_API_KEY` and `JWPLAYER_API_SECRET` ENV variables, you can simply do:
32
+
33
+ ```ruby
34
+ irb> client = JWPlayer::API::Client.new
35
+ => #<JWPlayer::API::Client:0x007fb6909e0158 @options={:host=>"api.jwplatform.com", :scheme=>"https", :version=>:v1, :key=>"y0c6CFQ5", :secret=>"YZWQ1SfmpFYEfW9kiR1QerRF", :format=>:json}>
36
+ ```
37
+
38
+ `JWPlayer::API::Client.new()` accepts the following optional parameters:
39
+
40
+ | Name | Default | Description |
41
+ |-----------|---------------------------------------|-------------|
42
+ | key | ENV['JWPLAYER_API_KEY'] | JWPlayer Platform API key
43
+ | secret | ENV['JWPLAYER_API_SECRET'] | JWPlayer Platform API secret
44
+ | host | 'api.jwplatform.com' | API host
45
+ | scheme | 'https' | API scheme
46
+ | version | :v1 | API version
47
+ | format | :json | API response format
48
+ | timestamp | current time | API UNIX timestamp used against replay-attacks
49
+ | nonce | automatically generated for each call | 8 digit random number
50
+ See https://developer.jwplayer.com/jw-platform/reference/v1/call_syntax.html for more information.
51
+
52
+ Then, you can get a signed uri or signed url like this:
53
+
54
+ ```ruby
55
+ irb> client.signed_uri('videos/create')
56
+ => #<URI::Generic https://api.jwplatform.com/v1/videos/create?api_format=json&api_key=y0c6CFQ5&api_nonce=36581160&api_signature=95c92965a690119b086e40e37c2bb9d9ef6d3781&api_timestamp=1462808317>
57
+
58
+ irb> client.signed_url('videos/create')
59
+ => "https://api.jwplatform.com/v1/videos/create?api_format=json&api_key=y0c6CFQ5&api_nonce=36581160&api_signature=95c92965a690119b086e40e37c2bb9d9ef6d3781&api_timestamp=1462808317"
60
+ ```
61
+
62
+ And with query parameters:
63
+
64
+ ```ruby
65
+ irb> client.signed_url('videos/create', title: 'My Super Video', description: 'This is cool')
66
+ => "https://api.jwplatform.com/v1/videos/create?api_format=json&api_key=y0b9GFQ3&api_nonce=36581160&api_signature=4b2e1d7c6aeda3c87e634300563159a5ba99b661&api_timestamp=1462808317&description=This%20is%20cool&title=My%20Super%20Video"
67
+ ```
68
+
69
+ ### IRL example
70
+
71
+ Create a video reference in your JWPlayer Dashboard and get the `media_id`:
72
+
73
+ ```ruby
74
+ require 'typhoeus'
75
+
76
+ data = {
77
+ author: 'Raphaël',
78
+ date: Date.new(2002,03,04).to_time.to_i,
79
+ description: 'Yet Another Keynote',
80
+ title: 'Apple Keynote',
81
+ source_format: :m3u8,
82
+ source_type: :url,
83
+ source_url: 'http://qthttp.apple.com.edgesuite.net/1010qwoeiuryfg/sl.m3u8'
84
+ }
85
+
86
+ # Call JWPlayer /videos/create API https://developer.jwplayer.com/jw-platform/reference/v1/methods/videos/create.html
87
+ jw_client = JWPlayer::API::Client.new
88
+ signed_url = jw_client.signed_url('videos/create', data)
89
+ response = Typhoeus.post(signed_url)
90
+ json = JSON.parse(response.body)
91
+ media_id = json.dig('media', 'key')
92
+ ```
93
+
94
+ ## Development
95
+
96
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
97
+
98
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
99
+
100
+ ## Contributing
101
+
102
+ Bug reports and pull requests are welcome on GitHub at https://github.com/raphi/jwplayer-api-client. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
103
+
104
+
105
+ ## License
106
+
107
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
108
+
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'jwplayer/api/client'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jwplayer/api/client/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'jwplayer-api-client'
8
+ spec.version = JWPlayer::API::Client::VERSION
9
+ spec.authors = ['Raphael Daguenet']
10
+ spec.email = ['raphael.daguenet@gmail.com']
11
+
12
+ spec.summary = 'JWPlayer client to easily sign URLs'
13
+ spec.description = 'This gem aims to easily sign JWPlayer Platform API URLs according to the documentation: https://developer.jwplayer.com/jw-platform/reference/v1/authentication.html'
14
+ spec.homepage = 'https://github.com/raphi/jwplayer-api-client'
15
+ spec.license = 'MIT'
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
+ else
22
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.11'
31
+ spec.add_development_dependency 'rake', '~> 11.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'digest'
5
+ require 'jwplayer/api/client/version'
6
+
7
+ module JWPlayer
8
+ module API
9
+ class Client
10
+ ALLOWED_KEYS = [:format, :key, :nonce, :timestamp]
11
+ IGNORED_KEYS = [:host, :scheme, :secret, :signature, :version]
12
+ ESCAPE_REGEX = /[^a-z0-9\-\.\_\~]/i # http://oauth.net/core/1.0/#encoding_parameters
13
+
14
+ attr_reader :params, :options
15
+
16
+ def initialize(args = {})
17
+ @options = {
18
+ host: 'api.jwplatform.com',
19
+ scheme: 'https',
20
+ version: :v1,
21
+ key: ENV['JWPLAYER_API_KEY'],
22
+ secret: ENV['JWPLAYER_API_SECRET'],
23
+ format: :json
24
+ }.merge(args)
25
+
26
+ [:key, :secret].each do |key|
27
+ if options[key].nil? || options[key].empty?
28
+ raise ArgumentError, "Missing :#{key} parameter or 'JWPLAYER_API_#{key.upcase}' ENV variable"
29
+ end
30
+ end
31
+ end
32
+
33
+ def signed_uri(path, params = {})
34
+ @params = params
35
+ @options[:nonce] = rand.to_s[2..9]
36
+ @options[:timestamp] = Time.now.to_i.to_s
37
+ @uri = URI.join(URI::Generic.build(@options), [@options[:version], '/'].join, path)
38
+ @uri.query = signed_attributes
39
+ @uri.normalize!
40
+ @uri
41
+ end
42
+
43
+ def signed_url(path, params = {})
44
+ signed_uri(path, params).to_s
45
+ end
46
+
47
+ private
48
+
49
+ #
50
+ # API signature generation
51
+ # https://developer.jwplayer.com/jw-platform/reference/v1/authentication.html#api-signature-generation
52
+ #
53
+
54
+ def attributes
55
+ matching_keys, extra_keys = options.keys.partition { |key| ALLOWED_KEYS.include?(key) }
56
+ extra_keys -= IGNORED_KEYS
57
+
58
+ raise ArgumentError, "#{self.class}: Unknown extra option keys\n [#{extra_keys.map(&:inspect).join(', ')}]" unless extra_keys.empty?
59
+
60
+ matching_keys.map { |key| [:"api_#{key}", options[key]] }
61
+ end
62
+
63
+ def signed_attributes
64
+ salted_params = salted_params(normalized_params)
65
+ signature = signature(salted_params)
66
+
67
+ to_query((params.to_a + attributes.to_a).push([:api_signature, signature]))
68
+ end
69
+
70
+ def normalized_params
71
+ to_query(signature_params)
72
+ end
73
+
74
+ def signature_params
75
+ sorted_params(params.to_a + attributes.to_a)
76
+ end
77
+
78
+ #
79
+ # Steps 1 and 2
80
+ # 1. All text parameters converted to UTF-8 encoding
81
+ # 2. All text parameters URL-encoded
82
+ #
83
+ def escape(value)
84
+ URI.escape(value.to_s, ESCAPE_REGEX)
85
+ end
86
+
87
+ #
88
+ # Step 3
89
+ # 3. Parameters are sorted based on their encoded names. Sort order is lexicographical byte value ordering
90
+ #
91
+ def sorted_params(params)
92
+ params.sort
93
+ end
94
+
95
+ #
96
+ # Step 4
97
+ # 4. Parameters are concatenated together into a single query string
98
+ #
99
+ def to_query(params)
100
+ params.map { |key, value| [key, escape(value)].join('=') }.join('&')
101
+ end
102
+
103
+ #
104
+ # Step 5
105
+ # The secret is added and SHA-1 digest is calculated
106
+ # Secret is added to the end of the SBS
107
+ #
108
+ def salted_params(query_string)
109
+ query_string + options[:secret].to_s
110
+ end
111
+
112
+ #
113
+ # Step 6
114
+ # The calculated SHA-1 HEX digest
115
+ #
116
+ def signature(token)
117
+ Digest::SHA1.hexdigest(token)
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,7 @@
1
+ module JWPlayer
2
+ module API
3
+ class Client
4
+ VERSION = '0.1.0'
5
+ end
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jwplayer-api-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Raphael Daguenet
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.11'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ description: 'This gem aims to easily sign JWPlayer Platform API URLs according to
56
+ the documentation: https://developer.jwplayer.com/jw-platform/reference/v1/authentication.html'
57
+ email:
58
+ - raphael.daguenet@gmail.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/console
71
+ - bin/setup
72
+ - jwplayer-api-client.gemspec
73
+ - lib/jwplayer/api/client.rb
74
+ - lib/jwplayer/api/client/version.rb
75
+ homepage: https://github.com/raphi/jwplayer-api-client
76
+ licenses:
77
+ - MIT
78
+ metadata:
79
+ allowed_push_host: https://rubygems.org
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.5.1
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: JWPlayer client to easily sign URLs
100
+ test_files: []