bigbluebutton-api-ruby 1.6.0 → 1.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 473e9baacfe50dd02c2de2799d1f9ef36d7fa086
4
- data.tar.gz: f8a35a9a314631bb3386382322fa2d5bee8c3a17
2
+ SHA256:
3
+ metadata.gz: d0441812c16477d28d431e085349d9b41dbb2487fa2714658d0f4257bfbfc696
4
+ data.tar.gz: d6ef204678952d1890225b2e66dd17e7aafb2a20733ffd2733b6a99c3a9383f1
5
5
  SHA512:
6
- metadata.gz: af669d4c0ea78a687001e1b0d1449da3a820f76c846ca3535942f2c56c86c1854cc3cd2d4d2614408b3cd1a3c233f2ef42683bd9bc9c7345cbeefd80dc4fbc99
7
- data.tar.gz: 283b0c7fd0d864f7b674372c3f85887fd6b4d67eab6e7ba686abb1b4c017740b94289b2f84e1e20fe35d82efe2396f9b9c19704a751dab7c7130b9e7ed662f1b
6
+ metadata.gz: 8a62b74b9922d8eae4ad5f28be54e5975c0bbc7e267a7da457f3c307ca3199a3bf82f6acc2361e419df9c7a3277882e66cf10ba9cd52f60f23f6a3a8a8e88faa
7
+ data.tar.gz: 8630d39007e82a5d3e0fd0ea623e51138a62726e1778170d03db1150220196906b7665d9caab3e4cf9b85eeebf11445ae7302670048ee8eee4fc7f7e2773235b
data/.gitignore CHANGED
@@ -5,4 +5,5 @@ features/config.yml
5
5
  logs/bbb.log
6
6
  rdoc/
7
7
  logs/*
8
- .bundle/
8
+ .bundle/
9
+ .volumes/
data/.rspec CHANGED
@@ -1 +1,2 @@
1
+ --format documentation
1
2
  --color
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.6.5
data/CHANGELOG.md CHANGED
@@ -1,13 +1,44 @@
1
1
  # Change Log
2
2
 
3
-
4
- ------------------------------------
5
-
6
- All tickets below use references to IDs in our old issue tracking system.
7
- To find them, search for their description or ID in the new issue tracker.
8
-
9
- ------------------------------------
10
-
3
+ ## [1.9.0] - 2022-05-03
4
+ * [#56] Add support for checksum using SHA256
5
+
6
+ [#56]: https://github.com/mconf/bigbluebutton-api-ruby/pull/56
7
+ [1.9.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.8.0...v1.9.0
8
+
9
+ ## [1.8.0] - 2021-12-06
10
+ * [#43] Add keys to every `BigBlueButtonException`, to better identify them.
11
+ * [#42] Change `BigBlueButtonException` to inherit from `StandardError` instead of `Exception`.
12
+ * [#50] [BREAKING-CHANGE] Replace `debug` flag with a optional Logger. The application using the
13
+ gem can pass its own logger as argument for the `BigBlueButtonApi` initialization.
14
+ If none is passed, the gem will use its own default logger on `STDOUT` with `INFO` level.
15
+ * [#40] Fix issue preventing documents from being preuploaded using the create call.
16
+ * Fix parse of recordings with invalid times. It would break at `getRecordings` if one
17
+ of them had an empty `startTime` or `endTime`.
18
+ * Add a Dockerfile and compose to help run tests.
19
+ * Fix deprecated `TimeoutError` constant.
20
+ * [#35] Make `get_recordings` accept multiple `state` params.
21
+ * [#34] Update `rubyzip` gem to the newest version with no vulnerability, from 1.2.2 to 1.3.0
22
+ * [#33] Upgrade dependencies:
23
+ - `childprocess` from 0.3.2 to 1.0.1
24
+ - `ffi` from 1.0.11 to 1.9.24
25
+ - `json` from 1.8.3 to 1.8.6
26
+ - `nokogiri` from 1.6.6.2 to 1.10.4
27
+ - `rack` from 1.4.1 to 1.6.11
28
+ - `rdoc` from 3.12 to 3.12.1
29
+ - `rubyzip` from 0.9.8 to 1.2.2
30
+
31
+ ## [1.7.0] - 2018-08-17
32
+
33
+ * [#29] Add support to the API call `updateRecordings` introduced in BigBlueButton 1.1.
34
+ * [#31] Fixed issue with length=nil breaking multiple recording formats.
35
+ * Call `setConfigXML` via POST and change encoding method. Fixes issues with special
36
+ characters (such as `*`) in the config.xml.
37
+ * Add method to return the URL to `/check`.
38
+
39
+ ## [1.6.0] - 2016-06-15
40
+
41
+ * Rename BigBlueButtonApi#salt to #secret
11
42
 
12
43
  ## [1.5.0] - 2016-04-07
13
44
 
@@ -141,6 +172,21 @@ were different in cases when they were not.
141
172
  (instead of browser URL). This call currently does not work as
142
173
  documented.
143
174
 
175
+ <!-- PRs -->
176
+ [#50]: https://github.com/mconf/bigbluebutton-api-ruby/pull/50
177
+ [#43]: https://github.com/mconf/bigbluebutton-api-ruby/pull/43
178
+ [#42]: https://github.com/mconf/bigbluebutton-api-ruby/pull/42
179
+ [#40]: https://github.com/mconf/bigbluebutton-api-ruby/pull/40
180
+ [#35]: https://github.com/mconf/bigbluebutton-api-ruby/pull/35
181
+ [#34]: https://github.com/mconf/bigbluebutton-api-ruby/pull/34
182
+ [#33]: https://github.com/mconf/bigbluebutton-api-ruby/pull/33
183
+ [#31]: https://github.com/mconf/bigbluebutton-api-ruby/pull/31
184
+ [#29]: https://github.com/mconf/bigbluebutton-api-ruby/pull/29
185
+
186
+ <!-- Versions -->
187
+ [1.8.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.7.0...v1.8.0
188
+ [1.7.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.6.0...v1.7.0
189
+ [1.6.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.5.0...v1.6.0
144
190
  [1.5.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.4.0...v1.5.0
145
191
  [1.4.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.3.0...v1.4.0
146
192
  [1.3.0]: https://github.com/mconf/bigbluebutton-api-ruby/compare/v1.2.0...v1.3.0
data/Dockerfile ADDED
@@ -0,0 +1,13 @@
1
+ FROM ruby:2.6.5
2
+
3
+ ENV app /usr/src/app
4
+
5
+ # Create app directory
6
+ RUN mkdir -p $app
7
+ WORKDIR $app
8
+
9
+ # Bundle app source
10
+ COPY . $app
11
+
12
+ # Install app dependencies
13
+ RUN bundle install
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ gemspec
4
4
 
5
5
  group :developement do
6
6
  gem 'rake', '>= 0.9'
7
- gem 'rdoc'
7
+ gem 'rdoc', '3.12.1'
8
8
  end
9
9
 
10
10
  group :development, :test do
data/Gemfile.lock CHANGED
@@ -7,7 +7,13 @@ GIT
7
7
  PATH
8
8
  remote: .
9
9
  specs:
10
- bigbluebutton-api-ruby (1.6.0)
10
+ bigbluebutton-api-ruby (1.9.0)
11
+ childprocess (>= 1.0.1)
12
+ ffi (>= 1.9.24)
13
+ json (>= 1.8.6)
14
+ nokogiri (>= 1.10.4)
15
+ rack (>= 1.6.11)
16
+ rubyzip (>= 1.3.0)
11
17
  xml-simple (~> 1.1)
12
18
 
13
19
  GEM
@@ -22,8 +28,8 @@ GEM
22
28
  rack-test (>= 0.5.4)
23
29
  selenium-webdriver (~> 2.0)
24
30
  xpath (~> 0.1.4)
25
- childprocess (0.3.2)
26
- ffi (~> 1.0.6)
31
+ childprocess (1.0.1)
32
+ rake (< 13.0)
27
33
  cucumber (1.1.9)
28
34
  builder (>= 2.1.2)
29
35
  diff-lcs (>= 1.1.2)
@@ -35,24 +41,25 @@ GEM
35
41
  cucumber (>= 1.1.8)
36
42
  nokogiri (>= 1.5.0)
37
43
  diff-lcs (1.1.3)
38
- ffi (1.0.11)
44
+ ffi (1.9.24)
39
45
  forgery (0.5.0)
40
46
  gherkin (2.9.3)
41
47
  json (>= 1.4.6)
42
- json (1.8.3)
48
+ json (1.8.6)
43
49
  libwebsocket (0.1.3)
44
50
  addressable
45
51
  mime-types (1.18)
46
- mini_portile (0.6.2)
52
+ mini_portile2 (2.4.0)
47
53
  multi_json (1.3.4)
48
- nokogiri (1.6.6.2)
49
- mini_portile (~> 0.6.0)
50
- rack (1.4.1)
54
+ nokogiri (1.10.4)
55
+ mini_portile2 (~> 2.4.0)
56
+ rack (1.6.11)
51
57
  rack-test (0.6.1)
52
58
  rack (>= 1.0)
53
59
  rake (0.9.2.2)
54
- rdoc (3.12)
60
+ rdoc (3.12.1)
55
61
  json (~> 1.4)
62
+ rexml (3.2.5)
56
63
  rspec (2.10.0)
57
64
  rspec-core (~> 2.10.0)
58
65
  rspec-expectations (~> 2.10.0)
@@ -61,7 +68,7 @@ GEM
61
68
  rspec-expectations (2.10.0)
62
69
  diff-lcs (~> 1.1.3)
63
70
  rspec-mocks (2.10.0)
64
- rubyzip (0.9.8)
71
+ rubyzip (1.3.0)
65
72
  selenium-webdriver (2.21.2)
66
73
  childprocess (>= 0.2.5)
67
74
  ffi (~> 1.0)
@@ -69,7 +76,8 @@ GEM
69
76
  multi_json (~> 1.0)
70
77
  rubyzip
71
78
  term-ansicolor (1.0.7)
72
- xml-simple (1.1.5)
79
+ xml-simple (1.1.9)
80
+ rexml
73
81
  xpath (0.1.4)
74
82
  nokogiri (~> 1.3)
75
83
 
@@ -82,5 +90,8 @@ DEPENDENCIES
82
90
  cucumber-rails
83
91
  forgery
84
92
  rake (>= 0.9)
85
- rdoc
93
+ rdoc (= 3.12.1)
86
94
  rspec (~> 2.10)
95
+
96
+ BUNDLED WITH
97
+ 1.17.3
data/Rakefile CHANGED
@@ -5,7 +5,8 @@ require 'rspec/core/rake_task'
5
5
  require 'cucumber/rake/task'
6
6
 
7
7
  desc 'Default: run tests.'
8
- task :default => [:spec, :cucumber]
8
+ # task :default => [:spec, :cucumber]
9
+ task :default => :spec
9
10
 
10
11
  RSpec::Core::RakeTask.new(:spec)
11
12
 
@@ -2,7 +2,7 @@ $:.push File.expand_path("../lib", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "bigbluebutton-api-ruby"
5
- s.version = "1.6.0"
5
+ s.version = "1.9.0"
6
6
  s.licenses = ["MIT"]
7
7
  s.extra_rdoc_files = ["README.md", "LICENSE", "LICENSE_003", "CHANGELOG.md"]
8
8
  s.summary = "BigBlueButton integration for ruby"
@@ -14,5 +14,11 @@ Gem::Specification.new do |s|
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.require_paths = ["lib"]
16
16
 
17
- s.add_runtime_dependency("xml-simple", "~> 1.1")
17
+ s.add_runtime_dependency('childprocess', '>= 1.0.1')
18
+ s.add_runtime_dependency('ffi', '>= 1.9.24')
19
+ s.add_runtime_dependency('json', '>= 1.8.6')
20
+ s.add_runtime_dependency('nokogiri', '>= 1.10.4')
21
+ s.add_runtime_dependency('rack', '>= 1.6.11')
22
+ s.add_runtime_dependency('rubyzip', '>= 1.3.0')
23
+ s.add_runtime_dependency('xml-simple', '~> 1.1')
18
24
  end
@@ -0,0 +1,10 @@
1
+ version: '2'
2
+ services:
3
+
4
+ test:
5
+ build: .
6
+ tty: true
7
+ volumes:
8
+ - $PWD:/usr/src/app
9
+ - .volumes/bundle/:/usr/local/bundle
10
+ command: bundle exec rake
@@ -1,4 +1,4 @@
1
- debug: false
1
+ logger: nil
2
2
 
3
3
  # maximum wait for a response to any API request (secs)
4
4
  timeout_req: 60
@@ -4,7 +4,7 @@ When /^the default BigBlueButton server$/ do
4
4
  @api = BigBlueButton::BigBlueButtonApi.new(@config_server['url'],
5
5
  @config_server['secret'],
6
6
  @config_server['version'].to_s,
7
- @config['debug'])
7
+ @config['logger'])
8
8
  @api.timeout = @config['timeout_req']
9
9
  end
10
10
 
@@ -2,6 +2,7 @@ require 'net/http'
2
2
  require 'cgi'
3
3
  require 'rexml/document'
4
4
  require 'digest/sha1'
5
+ require 'digest/sha2'
5
6
  require 'rubygems'
6
7
  require 'bigbluebutton_hash_to_xml'
7
8
  require 'bigbluebutton_exception'
@@ -9,6 +10,7 @@ require 'bigbluebutton_formatter'
9
10
  require 'bigbluebutton_modules'
10
11
  require 'bigbluebutton_config_xml'
11
12
  require 'bigbluebutton_config_layout'
13
+ require 'logger'
12
14
 
13
15
  module BigBlueButton
14
16
 
@@ -50,8 +52,8 @@ module BigBlueButton
50
52
  # API version e.g. 0.81
51
53
  attr_accessor :version
52
54
 
53
- # Flag to turn on/off debug mode
54
- attr_accessor :debug
55
+ # logger to log reponses and infos
56
+ attr_accessor :logger
55
57
 
56
58
  # Maximum wait time for HTTP requests (secs)
57
59
  attr_accessor :timeout
@@ -67,21 +69,29 @@ module BigBlueButton
67
69
  # url:: URL to a BigBlueButton server (e.g. http://demo.bigbluebutton.org/bigbluebutton/api)
68
70
  # secret:: Shared secret for this server
69
71
  # version:: API version e.g. 0.81
70
- def initialize(url, secret, version=nil, debug=false)
72
+ # logger:: Logger object to log actions (so apps can use their own loggers)
73
+ # sha256:: Flag to use sha256 when hashing url contents for checksum
74
+ def initialize(url, secret, version=nil, logger=nil, sha256=false)
71
75
  @supported_versions = ['0.8', '0.81', '0.9', '1.0']
72
76
  @url = url
73
77
  @secret = secret
74
- @debug = debug
75
78
  @timeout = 10 # default timeout for api requests
76
79
  @request_headers = {} # http headers sent in all requests
77
-
80
+ @logger = logger
81
+ @sha256 = sha256
82
+ # If logger is not informed, it defaults to STDOUT with INFO level
83
+ if logger.nil?
84
+ @logger = Logger.new(STDOUT)
85
+ @logger.level = Logger::INFO
86
+ end
87
+
78
88
  version = nil if version && version.strip.empty?
79
89
  @version = nearest_version(version || get_api_version)
80
90
  unless @supported_versions.include?(@version)
81
- puts "BigBlueButtonAPI: detected unsupported version, using the closest one that is supported (#{@version})"
91
+ @logger.warn("BigBlueButtonAPI: detected unsupported version, using the closest one that is supported (#{@version})")
82
92
  end
83
93
 
84
- puts "BigBlueButtonAPI: Using version #{@version}" if @debug
94
+ @logger.debug("BigBlueButtonAPI: Using version #{@version}")
85
95
  end
86
96
 
87
97
  # Creates a new meeting. Returns the hash with the response or throws BigBlueButtonException
@@ -226,7 +236,8 @@ module BigBlueButton
226
236
  # in this hash and they will be added to the API call.
227
237
  def join_meeting_url(meeting_id, user_name, password, options={})
228
238
  params = { :meetingID => meeting_id, :password => password, :fullName => user_name }.merge(options)
229
- get_url(:join, params)
239
+ url, data = get_url(:join, params)
240
+ url
230
241
  end
231
242
 
232
243
  # Returns a hash object containing the information of a meeting.
@@ -460,6 +471,10 @@ module BigBlueButton
460
471
  options[:meetingID] = options[:meetingID].join(",") if options[:meetingID].instance_of?(Array)
461
472
  end
462
473
 
474
+ if options.has_key?(:state)
475
+ options[:state] = options[:state].join(",") if options[:state].instance_of?(Array)
476
+ end
477
+
463
478
  response = send_api_request(:getRecordings, options)
464
479
 
465
480
  formatter = BigBlueButtonFormatter.new(response)
@@ -468,6 +483,30 @@ module BigBlueButton
468
483
  response
469
484
  end
470
485
 
486
+ # Available since BBB v1.1
487
+ # Update metadata (or other attributes depending on the API implementation) for a given recordID (or set of record IDs).
488
+ # recordIDs (string, Array):: ID or IDs of the target recordings.
489
+ # Any of the following values are accepted:
490
+ # "id1"
491
+ # "id1,id2,id3"
492
+ # ["id1"]
493
+ # ["id1", "id2", "id3"]
494
+ # meta (String):: Pass one or more metadata values to be update (format is the same as in create call)
495
+ # options (Hash):: Hash with additional parameters. This method doesn't accept additional
496
+ # parameters, but if you have a custom API with more parameters, you
497
+ # can simply pass them in this hash and they will be added to the API call.
498
+ #
499
+ # === Example responses
500
+ #
501
+ # { :returncode => success, :updated => true }
502
+ #
503
+ def update_recordings(recordIDs, meta=nil, options={})
504
+ recordIDs = recordIDs.join(",") if recordIDs.instance_of?(Array) # ["id1", "id2"] becomes "id1,id2"
505
+ params = { :recordID => recordIDs, :meta => meta }.merge(options)
506
+ send_api_request(:updateRecordings, params)
507
+ end
508
+
509
+
471
510
  # Publish and unpublish recordings for a given recordID (or set of record IDs).
472
511
  # recordIDs (string, Array):: ID or IDs of the target recordings.
473
512
  # Any of the following values are accepted:
@@ -599,10 +638,15 @@ module BigBlueButton
599
638
  response[:returncode]
600
639
  end
601
640
 
641
+ def check_url
642
+ url, data = get_url(:check)
643
+ url
644
+ end
645
+
602
646
  # API's are equal if all the following attributes are equal.
603
647
  def ==(other)
604
648
  r = true
605
- [:url, :supported_versions, :secret, :version, :debug].each do |param|
649
+ [:url, :supported_versions, :secret, :version, :logger].each do |param|
606
650
  r = r && self.send(param) == other.send(param)
607
651
  end
608
652
  r
@@ -623,11 +667,12 @@ module BigBlueButton
623
667
  # params (Hash):: The parameters to be passed in the URL
624
668
  def get_url(method, params={})
625
669
  if method == :index
626
- return @url
670
+ return @url, nil
671
+ elsif method == :check
672
+ baseurl = URI.join(@url, "/").to_s
673
+ return "#{baseurl}check", nil
627
674
  end
628
675
 
629
- url = "#{@url}/#{method}?"
630
-
631
676
  # stringify and escape all params
632
677
  params.delete_if { |k, v| v.nil? } unless params.nil?
633
678
  # some API calls require the params to be sorted
@@ -635,16 +680,22 @@ module BigBlueButton
635
680
  params = params.inject({}){ |memo,(k,v)| memo[k.to_sym] = v; memo }
636
681
  params = Hash[params.sort]
637
682
  params_string = ""
638
- params_string = params.map{ |k,v| "#{k}=" + CGI::escape(v.to_s) unless k.nil? || v.nil? }.join("&")
683
+ params_string = params.map{ |k,v| "#{k}=" + URI.encode_www_form_component(v.to_s) unless k.nil? || v.nil? }.join("&")
639
684
 
640
685
  # checksum calc
641
686
  checksum_param = params_string + @secret
642
687
  checksum_param = method.to_s + checksum_param
643
- checksum = Digest::SHA1.hexdigest(checksum_param)
688
+ checksum = @sha256 ? Digest::SHA256.hexdigest(checksum_param) : Digest::SHA1.hexdigest(checksum_param)
644
689
 
645
- # final url
646
- url += "#{params_string}&" unless params_string.empty?
647
- url += "checksum=#{checksum}"
690
+ if method == :setConfigXML
691
+ params_string = "checksum=#{checksum}&#{params_string}"
692
+ return "#{@url}/#{method}", params_string
693
+ else
694
+ url = "#{@url}/#{method}?"
695
+ url += "#{params_string}&" unless params_string.empty?
696
+ url += "checksum=#{checksum}"
697
+ return url, nil
698
+ end
648
699
  end
649
700
 
650
701
  # Performs an API call.
@@ -661,7 +712,9 @@ module BigBlueButton
661
712
  # raw (boolean):: If true, returns the data as it was received. Will not parse it into a Hash,
662
713
  # check for errors or throw exceptions.
663
714
  def send_api_request(method, params={}, data=nil, raw=false)
664
- url = get_url(method, params)
715
+ # if the method returns a body, use it as the data in the post request
716
+ url, body = get_url(method, params)
717
+ data = body if body
665
718
 
666
719
  @http_response = send_request(url, data)
667
720
  return {} if @http_response.body.empty?
@@ -700,7 +753,7 @@ module BigBlueButton
700
753
  # Otherwise uses GET
701
754
  def send_request(url, data=nil)
702
755
  begin
703
- puts "BigBlueButtonAPI: URL request = #{url}" if @debug
756
+ @logger.debug("BigBlueButtonAPI: URL request = #{url}")
704
757
  url_parsed = URI.parse(url)
705
758
  http = Net::HTTP.new(url_parsed.host, url_parsed.port)
706
759
  http.open_timeout = @timeout
@@ -710,17 +763,22 @@ module BigBlueButton
710
763
  if data.nil?
711
764
  response = http.get(url_parsed.request_uri, @request_headers)
712
765
  else
713
- puts "BigBlueButtonAPI: Sending as a POST request with data.size = #{data.size}" if @debug
714
- opts = { 'Content-Type' => 'text/xml' }.merge @request_headers
766
+ @logger.debug("BigBlueButtonAPI: Sending as a POST request with data.size = #{data.size}")
767
+ opts = { 'Content-Type' => 'application/xml' }.merge @request_headers
715
768
  response = http.post(url_parsed.request_uri, data, opts)
716
769
  end
717
- puts "BigBlueButtonAPI: URL response = #{response.body}" if @debug
770
+ @logger.info("BigBlueButtonAPI: request=#{url} response_status=#{response.class.name} response_code=#{response.code} message_key=#{response.message}")
771
+ @logger.debug("BigBlueButtonAPI: URL response = #{response.body}")
718
772
 
719
- rescue TimeoutError => error
720
- raise BigBlueButtonException.new("Timeout error. Your server is probably down: \"#{@url}\". Error: #{error}")
773
+ rescue Timeout::Error => error
774
+ exception = BigBlueButtonException.new("Timeout error. Your server is probably down: \"#{@url}\". Error: #{error}")
775
+ exception.key = 'TimeoutError'
776
+ raise exception
721
777
 
722
778
  rescue Exception => error
723
- raise BigBlueButtonException.new("Connection error. Your URL is probably incorrect: \"#{@url}\". Error: #{error}")
779
+ exception = BigBlueButtonException.new("Connection error. Your URL is probably incorrect: \"#{@url}\". Error: #{error}")
780
+ exception.key = 'IncorrectUrlError'
781
+ raise exception
724
782
  end
725
783
 
726
784
  response
@@ -736,7 +794,9 @@ module BigBlueButton
736
794
 
737
795
  # we don't allow older versions than the one supported, use an old version of the gem for that
738
796
  if Gem::Version.new(version) < Gem::Version.new(@supported_versions[0])
739
- raise BigBlueButtonException.new("BigBlueButton error: Invalid API version #{version}. Supported versions: #{@supported_versions.join(', ')}")
797
+ exception = BigBlueButtonException.new("BigBlueButton error: Invalid API version #{version}. Supported versions: #{@supported_versions.join(', ')}")
798
+ exception.key = 'APIVersionError'
799
+ raise exception
740
800
 
741
801
  # allow newer versions by using the newest one we support
742
802
  elsif Gem::Version.new(version) > Gem::Version.new(@supported_versions.last)
@@ -29,7 +29,9 @@ module BigBlueButton
29
29
  begin
30
30
  @xml = XmlSimple.xml_in(xml, opts)
31
31
  rescue Exception => e
32
- raise BigBlueButton::BigBlueButtonException.new("Error parsing the layouts XML. Error: #{e.message}")
32
+ exception = BigBlueButton::BigBlueButtonException.new("Error parsing the layouts XML. Error: #{e.message}")
33
+ exception.key = 'XMLParsingError'
34
+ raise exception
33
35
  end
34
36
  end
35
37
 
@@ -33,7 +33,9 @@ module BigBlueButton
33
33
  @xml = XmlSimple.xml_in(xml, opts)
34
34
  @original_string = self.as_string.clone
35
35
  rescue Exception => e
36
- raise BigBlueButton::BigBlueButtonException.new("Error parsing the config XML. Error: #{e.message}")
36
+ exception = BigBlueButton::BigBlueButtonException.new("Error parsing the config XML. Error: #{e.message}")
37
+ exception.key = 'XMLParsingError'
38
+ raise exception
37
39
  end
38
40
  end
39
41
  end
@@ -1,6 +1,6 @@
1
1
  module BigBlueButton
2
2
 
3
- class BigBlueButtonException < Exception
3
+ class BigBlueButtonException < StandardError
4
4
  attr_accessor :key
5
5
 
6
6
  def to_s
@@ -22,7 +22,7 @@ module BigBlueButton
22
22
  unless @hash.has_key?(key)
23
23
  0
24
24
  else
25
- @hash[key] = @hash[key].to_i
25
+ @hash[key] = @hash[key].to_i rescue 0
26
26
  end
27
27
  end
28
28
 
@@ -49,7 +49,9 @@ module BigBlueButton
49
49
  if value.is_a?(Numeric)
50
50
  result = value == 0 ? nil : DateTime.parse(Time.at(value/1000.0).to_s)
51
51
  else
52
- if value.downcase == "null"
52
+ if (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
53
+ result = nil
54
+ elsif value.is_a?(String) && (value.empty? || value.downcase == 'null')
53
55
  result = nil
54
56
  else
55
57
  # note: just in case the value comes as a string in the format: "Thu Sep 01 17:51:42 UTC 2011"
@@ -10,7 +10,9 @@ module BigBlueButton
10
10
  hash = XmlSimple.xml_in(xml_io, opts)
11
11
  return symbolize_keys(hash)
12
12
  rescue Exception => e
13
- raise BigBlueButtonException.new("Impossible to convert XML to hash. Error: #{e.message}")
13
+ exception = BigBlueButtonException.new("Impossible to convert XML to hash. Error: #{e.message}")
14
+ exception.key = 'XMLConversionError'
15
+ raise exception
14
16
  end
15
17
  end
16
18
 
@@ -7,8 +7,7 @@ describe BigBlueButton::BigBlueButtonApi do
7
7
  let(:url) { "http://server.com" }
8
8
  let(:secret) { "1234567890abcdefghijkl" }
9
9
  let(:version) { "0.81" }
10
- let(:debug) { false }
11
- let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, debug) }
10
+ let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version) }
12
11
 
13
12
  describe "#get_default_config_xml" do
14
13
  let(:response) { "<response><returncode>1</returncode></response>" }
@@ -7,8 +7,7 @@ describe BigBlueButton::BigBlueButtonApi do
7
7
  let(:url) { "http://server.com" }
8
8
  let(:secret) { "1234567890abcdefghijkl" }
9
9
  let(:version) { "0.9" }
10
- let(:debug) { false }
11
- let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, debug) }
10
+ let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version) }
12
11
 
13
12
  describe "#create_meeting" do
14
13
  context "accepts the new parameters" do
@@ -9,16 +9,17 @@ describe BigBlueButton::BigBlueButtonApi do
9
9
  # default variables and API object for all tests
10
10
  let(:url) { "http://server.com" }
11
11
  let(:secret) { "1234567890abcdefghijkl" }
12
- let(:debug) { false }
13
- let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, debug) }
12
+ let(:logger) { Logger.new(STDOUT) }
13
+ let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, logger) }
14
+ before { logger.level = Logger::INFO }
14
15
 
15
16
  describe "#initialize" do
16
17
  context "standard initialization" do
17
- subject { BigBlueButton::BigBlueButtonApi.new(url, secret, version, debug) }
18
+ subject { BigBlueButton::BigBlueButtonApi.new(url, secret, version, logger) }
18
19
  it { subject.url.should == url }
19
20
  it { subject.secret.should == secret }
20
21
  it { subject.version.should == version }
21
- it { subject.debug.should == debug }
22
+ it { subject.logger.should == logger }
22
23
  it { subject.timeout.should == 10 }
23
24
  it { subject.supported_versions.should include("0.8") }
24
25
  it { subject.supported_versions.should include("0.81") }
@@ -226,7 +227,7 @@ describe BigBlueButton::BigBlueButtonApi do
226
227
  :userID => "id123", :webVoiceConf => 12345678, :createTime => 9876543 }
227
228
  }
228
229
 
229
- before { api.should_receive(:get_url).with(:join, params).and_return("test-url") }
230
+ before { api.should_receive(:get_url).with(:join, params).and_return(["test-url", nil]) }
230
231
  it {
231
232
  options = { :userID => "id123", :webVoiceConf => 12345678, :createTime => 9876543 }
232
233
  api.join_meeting_url("meeting-id", "Name", "pw", options).should == "test-url"
@@ -340,15 +341,24 @@ describe BigBlueButton::BigBlueButtonApi do
340
341
  end
341
342
  end
342
343
 
344
+ describe "#check_url" do
345
+ context "when method = :check" do
346
+ it {
347
+ api.url = 'http://my-test-server.com/bigbluebutton/api'
348
+ api.check_url.should == 'http://my-test-server.com/check'
349
+ }
350
+ end
351
+ end
352
+
343
353
  describe "#==" do
344
- let(:api2) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, debug) }
354
+ let(:api2) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, logger) }
345
355
 
346
356
  context "compares attributes" do
347
357
  it { api.should == api2 }
348
358
  end
349
359
 
350
- context "differs #debug" do
351
- before { api2.debug = !api.debug }
360
+ context "differs #logger" do
361
+ before { api2.logger = !api.logger }
352
362
  it { api.should_not == api2 }
353
363
  end
354
364
 
@@ -400,14 +410,21 @@ describe BigBlueButton::BigBlueButtonApi do
400
410
  describe "#get_url" do
401
411
 
402
412
  context "when method = :index" do
403
- it { api.get_url(:index).should == api.url }
413
+ it { api.get_url(:index).should == [api.url, nil] }
414
+ end
415
+
416
+ context "when method = :check" do
417
+ it {
418
+ api.url = 'http://my-test-server.com/bigbluebutton/api'
419
+ api.get_url(:check).should == ['http://my-test-server.com/check', nil]
420
+ }
404
421
  end
405
422
 
406
423
  context "when method != :index" do
407
424
  context "validates the entire url" do
408
425
  context "with params" do
409
426
  let(:params) { { :param1 => "value1", :param2 => "value2" } }
410
- subject { api.get_url(:join, params) }
427
+ subject { api.get_url(:join, params)[0] }
411
428
  it {
412
429
  # the hash can be sorted differently depending on the ruby version
413
430
  if params.map{ |k,v| "#{k}" }.join =~ /^param1/
@@ -419,36 +436,72 @@ describe BigBlueButton::BigBlueButtonApi do
419
436
  end
420
437
 
421
438
  context "without params" do
422
- subject { api.get_url(:join) }
439
+ subject { api.get_url(:join)[0] }
423
440
  it { subject.should match(/#{url}\/join\?[^&]/) }
424
441
  end
425
442
  end
426
443
 
444
+ context "when method = :setConfigXML" do
445
+ it {
446
+ api.url = 'http://my-test-server.com/bigbluebutton/api'
447
+ response = api.get_url(:setConfigXML, { param1: 1, param2: 2 })
448
+ response[0].should eql('http://my-test-server.com/bigbluebutton/api/setConfigXML')
449
+ response[1].should match(/checksum=.*&param1=1&param2=2/)
450
+ }
451
+ end
452
+
427
453
  context "discards params with nil value" do
428
454
  let(:params) { { :param1 => "value1", :param2 => nil } }
429
- subject { api.get_url(:join, params) }
455
+ subject { api.get_url(:join, params)[0] }
430
456
  it { subject.should_not match(/param2=/) }
431
457
  end
432
458
 
433
459
  context "escapes all params" do
434
460
  let(:params) { { :param1 => "value with spaces", :param2 => "@$" } }
435
- subject { api.get_url(:join, params) }
461
+ subject { api.get_url(:join, params)[0] }
436
462
  it { subject.should match(/param1=value\+with\+spaces/) }
437
463
  it { subject.should match(/param2=%40%24/) }
438
464
  end
439
465
 
466
+ [ [' ', '+'],
467
+ ['*', '*']
468
+ ].each do |values|
469
+ context "escapes #{values[0].inspect} as #{values[1].inspect}" do
470
+ let(:params) { { param1: "before#{values[0]}after" } }
471
+ subject { api.get_url(:join, params)[0] }
472
+ it { subject.should match(/param1=before#{Regexp.quote(values[1])}after/) }
473
+ end
474
+ end
475
+
440
476
  context "includes the checksum" do
441
- let(:params) { { :param1 => "value1", :param2 => "value2" } }
442
- let(:checksum) {
443
- # the hash can be sorted differently depending on the ruby version
444
- if params.map{ |k,v| "#{k}" }.join =~ /^param1/
445
- "67882ae54f49600f56f358c10d24697ef7d8c6b2"
446
- else
447
- "85a54e28e4ec18bfdcb214a73f74d35b09a84176"
448
- end
449
- }
450
- subject { api.get_url(:join, params) }
451
- it { subject.should match(/checksum=#{checksum}$/) }
477
+ context "when @sha256 is false or nil" do
478
+ let(:params) { { param1: "value1", param2: "value2" } }
479
+ let(:checksum) {
480
+ # the hash can be sorted differently depending on the ruby version
481
+ if params.map{ |k, v| k }.join =~ /^param1/
482
+ "67882ae54f49600f56f358c10d24697ef7d8c6b2"
483
+ else
484
+ "85a54e28e4ec18bfdcb214a73f74d35b09a84176"
485
+ end
486
+ }
487
+ subject { api.get_url(:join, params)[0] }
488
+ it('uses SHA1') { subject.should match(/checksum=#{checksum}$/) }
489
+ end
490
+
491
+ context "when @sha256 flag is true" do
492
+ let(:api) { BigBlueButton::BigBlueButtonApi.new(url, secret, version, logger, true) }
493
+ let(:params) { { param1: "value1", param2: "value2" } }
494
+ let(:checksum) {
495
+ # the hash can be sorted differently depending on the ruby version
496
+ if params.map{ |k,v| k }.join =~ /^param1/
497
+ "0e7b1611809fad890a114dddae1a37fecf14c28971afc10ee3eac432da5b8b41"
498
+ else
499
+ "21bf2d24c27251c4b2b2f0d5dd4b966a2f16fbfc7882e102b44c6d67f728f0c8"
500
+ end
501
+ }
502
+ subject { api.get_url(:join, params)[0] }
503
+ it('uses SHA256') { subject.should match(/checksum=#{checksum}$/) }
504
+ end
452
505
  end
453
506
  end
454
507
  end
@@ -461,7 +514,7 @@ describe BigBlueButton::BigBlueButtonApi do
461
514
  let(:make_request) { api.send_api_request(method, params, data) }
462
515
  let(:response_mock) { mock() } # mock of what send_request() would return
463
516
 
464
- before { api.should_receive(:get_url).with(method, params).and_return(url) }
517
+ before { api.should_receive(:get_url).with(method, params).and_return([url, nil]) }
465
518
 
466
519
  context "returns an empty hash if the response body is empty" do
467
520
  before do
@@ -524,17 +577,19 @@ describe BigBlueButton::BigBlueButtonApi do
524
577
  describe "#send_request" do
525
578
  let(:url) { "http://test-server:8080/res?param1=value1&checksum=12345" }
526
579
  let(:url_parsed) { URI.parse(url) }
580
+ let(:res) { Net::HTTPResponse.new(1.0, '200', 'OK') }
527
581
 
528
582
  before do
529
583
  @http_mock = mock(Net::HTTP)
530
584
  @http_mock.should_receive(:"open_timeout=").with(api.timeout)
531
585
  @http_mock.should_receive(:"read_timeout=").with(api.timeout)
532
586
  Net::HTTP.should_receive(:new).with("test-server", 8080).and_return(@http_mock)
587
+ res.stub(:body) { "ok" }
533
588
  end
534
589
 
535
590
  context "standard case" do
536
- before { @http_mock.should_receive(:get).with("/res?param1=value1&checksum=12345", {}).and_return("ok") }
537
- it { api.send(:send_request, url).should == "ok" }
591
+ before { @http_mock.should_receive(:get).with("/res?param1=value1&checksum=12345", {}).and_return(res) }
592
+ it { api.send(:send_request, url).should == res }
538
593
  end
539
594
 
540
595
  context "handles a TimeoutError" do
@@ -551,20 +606,20 @@ describe BigBlueButton::BigBlueButtonApi do
551
606
  let(:data) { "any data" }
552
607
  before {
553
608
  path = "/res?param1=value1&checksum=12345"
554
- opts = { 'Content-Type' => 'text/xml' }
555
- @http_mock.should_receive(:post).with(path, data, opts).and_return("ok")
609
+ opts = { 'Content-Type' => 'application/xml' }
610
+ @http_mock.should_receive(:post).with(path, data, opts).and_return(res)
556
611
  }
557
612
  it {
558
- api.send(:send_request, url, data).should == "ok"
613
+ api.send(:send_request, url, data).should == res
559
614
  }
560
615
  end
561
616
 
562
617
  context "get with headers" do
563
618
  let(:headers_hash) { { :anything => "anything" } }
564
- before { @http_mock.should_receive(:get).with("/res?param1=value1&checksum=12345", headers_hash).and_return("ok") }
619
+ before { @http_mock.should_receive(:get).with("/res?param1=value1&checksum=12345", headers_hash).and_return(res) }
565
620
  it {
566
621
  api.request_headers = headers_hash
567
- api.send(:send_request, url).should == "ok"
622
+ api.send(:send_request, url).should == res
568
623
  }
569
624
  end
570
625
 
@@ -573,12 +628,12 @@ describe BigBlueButton::BigBlueButtonApi do
573
628
  let(:data) { "any data" }
574
629
  before {
575
630
  path = "/res?param1=value1&checksum=12345"
576
- opts = { 'Content-Type' => 'text/xml', :anything => "anything" }
577
- @http_mock.should_receive(:post).with(path, data, opts).and_return("ok")
631
+ opts = { 'Content-Type' => 'application/xml', :anything => "anything" }
632
+ @http_mock.should_receive(:post).with(path, data, opts).and_return(res)
578
633
  }
579
634
  it {
580
635
  api.request_headers = headers_hash
581
- api.send(:send_request, url, data).should == "ok"
636
+ api.send(:send_request, url, data).should == res
582
637
  }
583
638
  end
584
639
  end
@@ -755,4 +810,5 @@ describe BigBlueButton::BigBlueButtonApi do
755
810
  it_should_behave_like "BigBlueButtonApi", "0.8"
756
811
  it_should_behave_like "BigBlueButtonApi", "0.81"
757
812
  it_should_behave_like "BigBlueButtonApi", "0.9"
813
+ it_should_behave_like "BigBlueButtonApi", "1.0"
758
814
  end
@@ -100,14 +100,43 @@ describe BigBlueButton::BigBlueButtonFormatter do
100
100
  it { hash[:param7].should == nil }
101
101
  it { hash[:param8].should == nil }
102
102
 
103
- context "returns nil if the param doesn't exists" do
104
- subject { BigBlueButton::BigBlueButtonFormatter.new({ :param => 1}) }
105
- it { subject.to_datetime(:inexistent).should == nil }
106
- end
103
+ context "returns nil if" do
104
+ context "the param doesn't exists" do
105
+ subject { BigBlueButton::BigBlueButtonFormatter.new({ :param => 1}) }
106
+ it { subject.to_datetime(:inexistent).should == nil }
107
+ end
107
108
 
108
- context "returns nil if the hash is nil" do
109
- subject { BigBlueButton::BigBlueButtonFormatter.new(nil) }
110
- it { subject.to_datetime(:inexistent).should == nil }
109
+ context "the hash is nil" do
110
+ subject { BigBlueButton::BigBlueButtonFormatter.new(nil) }
111
+ it { subject.to_datetime(:inexistent).should == nil }
112
+ end
113
+
114
+ context "the value is an empty string" do
115
+ subject { BigBlueButton::BigBlueButtonFormatter.new({ param1: '' }) }
116
+ it { subject.to_datetime(:param1).should == nil }
117
+ end
118
+
119
+ context "the value is nil" do
120
+ subject { BigBlueButton::BigBlueButtonFormatter.new({ param1: nil }) }
121
+ it { subject.to_datetime(:param1).should == nil }
122
+ end
123
+
124
+ context "the value is an empty hash" do
125
+ subject { BigBlueButton::BigBlueButtonFormatter.new({ param1: {} }) }
126
+ it { subject.to_datetime(:param1).should == nil }
127
+ end
128
+
129
+ context "the value is an empty array" do
130
+ subject { BigBlueButton::BigBlueButtonFormatter.new({ param1: [] }) }
131
+ it { subject.to_datetime(:param1).should == nil }
132
+ end
133
+
134
+ ['null', 'NULL'].each do |v|
135
+ context "the value is '#{v}'" do
136
+ subject { BigBlueButton::BigBlueButtonFormatter.new({ param1: v }) }
137
+ it { subject.to_datetime(:param1).should == nil }
138
+ end
139
+ end
111
140
  end
112
141
  end
113
142
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bigbluebutton-api-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mconf
@@ -9,8 +9,92 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-06-15 00:00:00.000000000 Z
12
+ date: 2022-05-03 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: childprocess
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 1.0.1
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 1.0.1
28
+ - !ruby/object:Gem::Dependency
29
+ name: ffi
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.9.24
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 1.9.24
42
+ - !ruby/object:Gem::Dependency
43
+ name: json
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: 1.8.6
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.8.6
56
+ - !ruby/object:Gem::Dependency
57
+ name: nokogiri
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.10.4
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 1.10.4
70
+ - !ruby/object:Gem::Dependency
71
+ name: rack
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 1.6.11
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.6.11
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubyzip
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.3.0
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 1.3.0
14
98
  - !ruby/object:Gem::Dependency
15
99
  name: xml-simple
16
100
  requirement: !ruby/object:Gem::Requirement
@@ -43,6 +127,7 @@ files:
43
127
  - ".ruby-version"
44
128
  - ".travis.yml"
45
129
  - CHANGELOG.md
130
+ - Dockerfile
46
131
  - Gemfile
47
132
  - Gemfile.lock
48
133
  - LICENSE
@@ -50,6 +135,7 @@ files:
50
135
  - README.md
51
136
  - Rakefile
52
137
  - bigbluebutton-api-ruby.gemspec
138
+ - docker-compose.yml
53
139
  - examples/config_xml.rb
54
140
  - examples/create.rb
55
141
  - examples/get_version_example.rb
@@ -113,8 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
199
  - !ruby/object:Gem::Version
114
200
  version: '0'
115
201
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.4.5
202
+ rubygems_version: 3.0.3
118
203
  signing_key:
119
204
  specification_version: 4
120
205
  summary: BigBlueButton integration for ruby