bigbluebutton-api-ruby 1.6.0 → 1.9.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
- 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