Birst_Command 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: e0ee23d32e4fa3869a26a0cc73406eb49759998a
4
+ data.tar.gz: 5625f8e217f41f750ef6d59b6c62398edc869e9c
5
+ SHA512:
6
+ metadata.gz: 2ffdf314e6da5db90dd83298a5b2c1023541f6d90913057b43b3068d489629105cdf5b55aace2c8f74ff0977e8ae15546ca5c5dad968e59c680a3145afd18c48
7
+ data.tar.gz: 96dcb93b1b2e2f752c97e2840edb5bd339821772a42ad8ad51423f7af077fa7de5775e47ae4b555f75b6e9be6e6136ac28679f9fb54e0647808910d0614d6c8b
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_DISABLE_SHARED_GEMS: '1'
@@ -0,0 +1,3 @@
1
+ *~
2
+ /vendor
3
+ /config.json
@@ -0,0 +1 @@
1
+ 2.0.0-p353
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require 'Birst_Command/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "Birst_Command"
8
+ s.version = Birst_Command::VERSION
9
+ s.authors = ["Sterling Paramore"]
10
+ s.email = ["gnilrets@gmail.com"]
11
+ s.homepage = "https://github.com/gnilrets"
12
+ s.license = "MIT"
13
+ s.summary = "Birst Command"
14
+ s.description = "Ruby interface to Birst web API"
15
+
16
+ s.rubyforge_project = "Birst_Command"
17
+ s.add_runtime_dependency "savon", ["~> 2.0"]
18
+ s.add_runtime_dependency "httpclient", ["~> 2.3"]
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ["lib"]
24
+ end
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gem 'savon', '~> 2.0'
3
+ gem 'httpclient'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Sterling Paramore
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,127 @@
1
+ Birst_Command
2
+ ====================
3
+
4
+ Birst Command is a Ruby gem that allows you to build Ruby scripts that interface
5
+ with the Birst Web API.
6
+
7
+
8
+ # Installation & Setup
9
+
10
+ Install the gem using `gem install Birst_Command` or using rvm or
11
+ rbenv/bundler as you prefer.
12
+
13
+ After installing, you'll need to create a Birst Command config file that contains
14
+ the credentials you'll use to connect to Birst. This config file should look like,
15
+
16
+ {
17
+ "wsdl": "https://login.bws.birst.com/CommandWebService.asmx?WSDL",
18
+ "endpoint": "https://login.bws.birst.com/CommandWebService.asmx",
19
+ "username": "name@myplace.com",
20
+ "password": "obfuscated pwd"
21
+ }
22
+
23
+ Most users should only need to modify the username and password. Since I have a strong
24
+ aversion to storing passwords in plaintext, the password in the config file needs to
25
+ be an obfuscated password. Birst Command comes with a password obfuscator that can be
26
+ executed via
27
+
28
+ $ obfuscate_pwd.rb mypassword
29
+ 0x8GOZ5nA3oRSSS8ao1l6Q==
30
+
31
+ Copy and paste the obfuscated password into the config file and **save
32
+ to a secure location**. If any attacker is able to get your
33
+ obfuscated password and knows it was created using this program, it
34
+ would be trivial to get your Birst login credentials.
35
+
36
+
37
+ # Usage
38
+
39
+ In your Ruby program, include the Birst Command gem and load the config file via
40
+
41
+ require 'rubygems'
42
+ require 'bundler/setup'
43
+ require 'Birst_Command'
44
+
45
+ Birst_Command::Config.read_config(File.join(File.dirname(__FILE__),"config.json"))
46
+
47
+ Birst commands are submitted in session blocks, which automatically perform the
48
+ process of logging in, tracking the login token, and logging out. For example,
49
+ to list all spaces that you have rights to, you can submit the following code
50
+
51
+ Birst_Command::Session.start do |bc|
52
+ spaces = bc.list_spaces
53
+ puts "#{JSON.pretty_generate spaces}"
54
+ end
55
+
56
+ Which would return something like
57
+
58
+ {
59
+ "user_space": [
60
+ {
61
+ "name": "MyGreatSpace",
62
+ "owner": "name@myplace.com",
63
+ "id": "b413207d-3fe2-4309-1b4a-ac8e961daad2"
64
+ },
65
+ {
66
+ "name": "MyOtherGreatSpace",
67
+ "owner": "name@myplace.com",
68
+ "id": "a113207d-3fe2-4310-1b4a-b58e961da123"
69
+ }
70
+ ]
71
+ }
72
+
73
+ The `spaces` variable is a Ruby hash parsed from the SOAP response.
74
+ The structure of the returned hash follows the structure that Birst
75
+ returns.
76
+
77
+
78
+ ## Helper Methods
79
+
80
+ I find some of the Birst API responses to be rather cumbersome. For
81
+ example, why do I need hash with a single `user_space` key? I'd
82
+ rather have an array of hashes here. To that end I find it convenient
83
+ to define helper methods that extend the Session class to simplify
84
+ some of this. To override the return value of the native
85
+ `list_spaces` command, you can do the following
86
+
87
+ class Birst_Command::Session
88
+ def list_spaces(*args)
89
+ result = command __method__, *args
90
+ [result[:user_space]].flatten
91
+ end
92
+ end
93
+
94
+ You can then execute the same `list_spaces` command above, but you get
95
+ an array of hashes rather than hash with a key that points to an array
96
+ of hashes.
97
+
98
+ I have not included any of these helper methods in the Birst Command
99
+ gem because what I find helpful, you may not. Birst Command just
100
+ provides the basic interface.
101
+
102
+ ## Command arguments
103
+
104
+ Some Birst API commands require arguments. All arguments are supplied as an argument
105
+ hash. For example, to create a new space,
106
+
107
+ Birst_Command::Session.start do |bc|
108
+ new_space_id = bc.create_new_space :spaceName => "myNewSpace",
109
+ :comments => "Just testing",
110
+ :automatic => "false"
111
+ end
112
+
113
+ ## camelCase/snake_case issues
114
+
115
+ Birst Command uses [Savon](http://savonrb.com/version2/client.html) as
116
+ the underlying framework used to communicate with the Birst SOAP API.
117
+ Savon expects commands in snake_case format and converts them into
118
+ camelCase when submitted to the Birst API (e.g., `list_spaces` is
119
+ converted to `listSpaces`). This behavior is *not* configurable.
120
+ Savon also has options for converting the arguments of parameters from
121
+ snake_case into camelCase. Unfortunately, the Birst Web API is not
122
+ entirely consistent in its use of camelCase for arguments (e.g.,
123
+ `spaceId` is used in `deleteSpace` but `spaceID` is used in
124
+ `listUsersInSpace`). This inconsistency requires us to **submit
125
+ commands as snake_case and arguments as the camelCase that Birst
126
+ uses.**
127
+
@@ -0,0 +1,14 @@
1
+ # -*- mode: ruby -*-
2
+
3
+ require 'rake/testtask'
4
+
5
+ task :default => [:test_all]
6
+
7
+ # Run a specific unit test with `rake test TEST=test/Datalib/test_datalib.rb`
8
+ Rake::TestTask.new do |t|
9
+
10
+ t.libs << "test"
11
+ t.test_files = FileList['test/*/test_*.rb']
12
+ t.verbose = true
13
+
14
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__),"..","lib","birst_command")
3
+
4
+ begin
5
+ puts Obfuscate.obfuscate(ARGV[0])
6
+ rescue
7
+ puts "USAGE: ./obfuscate_pwd <plaintxt password>"
8
+ end
9
+
@@ -0,0 +1,6 @@
1
+ {
2
+ "wsdl": "https://login.bws.birst.com/CommandWebService.asmx?WSDL",
3
+ "endpoint": "https://login.bws.birst.com/CommandWebService.asmx",
4
+ "username": "name@myplace.com",
5
+ "password": "obfuscated pwd"
6
+ }
@@ -0,0 +1,10 @@
1
+ require 'savon'
2
+ require 'httpclient'
3
+ require 'openssl'
4
+ require 'base64'
5
+ require 'json'
6
+
7
+ require 'birst_command/config'
8
+ require 'birst_command/obfuscate'
9
+ require 'birst_command/session'
10
+
@@ -0,0 +1,25 @@
1
+ module Birst_Command
2
+ module Config
3
+ extend self
4
+
5
+ attr_accessor :config_full_path
6
+ @config_full_path = File.join(File.dirname(__FILE__),"../../config.json")
7
+
8
+ attr_accessor :options
9
+ @options = {
10
+ :soap_log_level => :error,
11
+ :soap_log => false
12
+ }
13
+
14
+ def read_config(config_full_path = @config_full_path)
15
+ @options = @options.merge!(JSON.parse(IO.read(config_full_path), :symbolize_names => true))
16
+ end
17
+
18
+ def set_debug
19
+ @options = @options.merge!({
20
+ :soap_log_level => :debug,
21
+ :soap_log => true
22
+ })
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ module Birst_Command
2
+ module Obfuscate
3
+ extend self
4
+
5
+ @crypt_pwd = "BirstIsAwesome"
6
+ @salt = "31415927"
7
+ @cypher = "AES-128-CBC"
8
+
9
+ def obfuscate(pwd)
10
+ # Returns a base64-obfuscated password to be stored in the config.json file
11
+ encrypter = OpenSSL::Cipher::Cipher.new @cypher
12
+ encrypter.encrypt
13
+ encrypter.pkcs5_keyivgen @crypt_pwd, @salt
14
+
15
+ encrypted = encrypter.update pwd
16
+ encrypted << encrypter.final
17
+
18
+ Base64.encode64(encrypted).chomp
19
+ end
20
+
21
+
22
+ def deobfuscate(obfuscated_pwd)
23
+ # Returns a plaintext password
24
+ decrypter = OpenSSL::Cipher::Cipher.new @cypher
25
+ decrypter.decrypt
26
+ decrypter.pkcs5_keyivgen @crypt_pwd, @salt
27
+
28
+ plain = decrypter.update Base64.decode64(obfuscated_pwd)
29
+ plain << decrypter.final
30
+
31
+ plain
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,70 @@
1
+ module Birst_Command
2
+ class Session
3
+ def initialize
4
+ @options = Birst_Command::Config.options
5
+
6
+ @client = Savon.client(
7
+ wsdl: @options[:wsdl],
8
+ endpoint: @options[:endpoint],
9
+ convert_request_keys_to: :none,
10
+ soap_version: 1,
11
+ pretty_print_xml: true,
12
+ filters: [:password],
13
+ log_level: @options[:soap_log_level],
14
+ log: @options[:soap_log]
15
+ )
16
+
17
+ @response = nil
18
+ @token = nil
19
+ @auth_cookies = nil
20
+ end
21
+
22
+ attr_reader :token
23
+ attr_reader :auth_cookies
24
+ attr_reader :response
25
+
26
+
27
+ def self.start(&b)
28
+ session = self.new
29
+ session.login
30
+ session.execute_block(&b)
31
+ ensure
32
+ session.logout
33
+ end
34
+
35
+
36
+ def login
37
+ @response = @client.call(:login,
38
+ message: {
39
+ username: @options[:username],
40
+ password: Obfuscate.deobfuscate(@options[:password])
41
+ })
42
+
43
+ @auth_cookies = @response.http.cookies
44
+ @token = @response.hash[:envelope][:body][:login_response][:login_result]
45
+ end
46
+
47
+
48
+ def execute_block(&b)
49
+ yield self
50
+ end
51
+
52
+
53
+ def method_missing(command_name, *args)
54
+ command command_name, *args
55
+ end
56
+
57
+
58
+ def command(command_name, *args)
59
+ response_key = "#{command_name}_response".to_sym
60
+ result_key = "#{command_name}_result".to_sym
61
+
62
+ message = args.last.is_a?(Hash) ? args.pop : {}
63
+ result = @client.call command_name,
64
+ cookies: @auth_cookies,
65
+ message: { :token => @token }.merge(message)
66
+
67
+ result.hash[:envelope][:body][response_key][result_key]
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module Birst_Command
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1 @@
1
+ /config_test.json
@@ -0,0 +1,8 @@
1
+ {
2
+ "test": {
3
+ "test_add_user_to_space": {
4
+ "username": "mytestuser@company.com",
5
+ "space_id": "MYTESTSPACEID"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "username": "name@myplace.com",
3
+ "password": "obfuscated pwd"
4
+ }
@@ -0,0 +1,49 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_add_user_to_space < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Birst_Command::Config.read_config
7
+ Birst_Command::Config.read_config(File.join(File.dirname(__FILE__),"../config_test.json"))
8
+ @test_options = Birst_Command::Config.options[:test][:test_add_user_to_space]
9
+ end
10
+
11
+
12
+ def teardown
13
+ end
14
+
15
+
16
+ def user_exists?
17
+ result = nil
18
+ Session.start do |bc|
19
+ users = bc.list_users_in_space :spaceID => @test_options[:space_id]
20
+ result = [users[:string]].flatten.include? @test_options[:username]
21
+ end
22
+ result
23
+ end
24
+
25
+
26
+ def test_add_user_to_space
27
+ Session.start do |bc|
28
+ bc.add_user_to_space :userName => @test_options[:username],
29
+ :spaceID => @test_options[:space_id],
30
+ :hasAdmin => "false"
31
+ end
32
+
33
+ assert user_exists?, "User #{@test_options[:username]} not added!"
34
+ end
35
+
36
+
37
+ def test_remove_user_from_space
38
+ test_add_user_to_space if !user_exists?
39
+
40
+ Session.start do |bc|
41
+ bc.remove_user_from_space :userName => @test_options[:username],
42
+ :spaceID => @test_options[:space_id]
43
+ end
44
+
45
+ assert !user_exists?, "User #{@test_options[:username]} should no longer exist!"
46
+ end
47
+ end
48
+
49
+
@@ -0,0 +1,44 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_command_helper < Test::Unit::TestCase
4
+
5
+ # Decided that commands should return whatever the Birst API returns.
6
+ # However, for user code, it would be helpful to customize returns for
7
+ # specific use cases
8
+
9
+ class Session < Birst_Command::Session
10
+ def list_spaces(*args)
11
+ result = command __method__, *args
12
+ [result[:user_space]].flatten
13
+ end
14
+ def list_users_in_space(*args)
15
+ result = command __method__, *args
16
+ [result[:string]].flatten
17
+ end
18
+ end
19
+
20
+
21
+ def setup
22
+ Birst_Command::Config.read_config
23
+ Birst_Command::Config.read_config(File.join(File.dirname(__FILE__),"../config_test.json"))
24
+ end
25
+
26
+ def teardown
27
+ end
28
+
29
+ def test_add_user_to_space
30
+ test_options = Birst_Command::Config.options[:test][:test_add_user_to_space]
31
+
32
+ spaces = nil
33
+ users = nil
34
+ Session.start do |bc|
35
+ spaces = bc.list_spaces
36
+ users = bc.list_users_in_space :spaceID => test_options[:space_id]
37
+ end
38
+
39
+ assert spaces.is_a?(Array), "list_spaces helper did not return an array"
40
+ assert !spaces[0].has_key?(:user_space), "list_spaces helper should not give :user_space"
41
+ end
42
+ end
43
+
44
+
@@ -0,0 +1,55 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_copy_space < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Birst_Command::Config.read_config
7
+ Birst_Command::Config.read_config(File.join(File.dirname(__FILE__),"../config_test.json"))
8
+ @new_space_id = nil
9
+ end
10
+
11
+ def teardown
12
+ Session.start do |bc|
13
+ bc.delete_space :spaceId => @new_space_id
14
+ end
15
+ end
16
+
17
+ def test_copy_space
18
+ test_options = Birst_Command::Config.options[:test][:test_copy_space]
19
+
20
+ Session.start do |bc|
21
+ @new_space_id = bc.create_new_space :spaceName => "test_copy_space",
22
+ :comments => "",
23
+ :automatic => "false"
24
+
25
+ puts "#{JSON.pretty_generate bc.list_spaces}"
26
+ job_token = bc.copy_space :spFromID => test_options[:from_space_id],
27
+ :spToID => @new_space_id,
28
+ :mode => "copy",
29
+ :options => "data;settings-permissions;settings-membership;repository;birst-connect;custom-subject-areas;dashboardstyles;salesforce;catalog;CustomGeoMaps.xml;spacesettings.xml;SavedExpressions.xml;DrillMaps.xml;connectors;datastore-aggregates;settings-basic"
30
+
31
+
32
+ i = 0
33
+ loop do
34
+ i += 1
35
+ if i < 60
36
+ status = bc.get_job_status :jobToken => job_token
37
+ puts "#{JSON.pretty_generate status}"
38
+
39
+ is_job_complete = bc.is_job_complete :jobToken => job_token
40
+ puts "COMPLETE? #{is_job_complete}"
41
+ sleep 1
42
+
43
+ break if is_job_complete
44
+ else
45
+ raise "Copy job timed out"
46
+ end
47
+ end
48
+
49
+
50
+ end
51
+
52
+ assert_equal 36, @new_space_id.length, "Got an invalid space id #{@new_space_id}"
53
+ end
54
+ end
55
+
@@ -0,0 +1,23 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_deobfuscate < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @pwd = "mysecretpass"
7
+ @obs_pwd = "IQX4os6wCE7rl+JuSYL2Iw=="
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_obfuscate
14
+ assert_equal @obs_pwd, Obfuscate.obfuscate(@pwd), "Expecting password #{@obs_pwd}"
15
+ end
16
+
17
+ def test_deobfuscate
18
+ assert_equal @pwd, Obfuscate.deobfuscate(@obs_pwd), "Expecting password #{@pwd}"
19
+ end
20
+
21
+ end
22
+
23
+
@@ -0,0 +1,24 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_list_spaces < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Birst_Command::Config.read_config
7
+ end
8
+
9
+ def teardown
10
+ end
11
+
12
+ def test_list_spaces
13
+ spaces = nil
14
+ Session.start do |bc|
15
+ unclean_spaces = bc.list_spaces
16
+ spaces = [unclean_spaces[:user_space]].flatten
17
+ end
18
+
19
+ assert spaces.is_a?(Array), "Expecting spaces to be an array"
20
+ assert spaces[0].is_a?(Hash), "Expecting spaces to be an array of hashes"
21
+ end
22
+ end
23
+
24
+
@@ -0,0 +1,23 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_login < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Birst_Command::Config.read_config
7
+ end
8
+
9
+ def teardown
10
+ end
11
+
12
+ def test_login
13
+ token = ""
14
+ Session.start do |bc|
15
+ token = bc.token
16
+ end
17
+
18
+ assert_equal 32, token.length, "Got an invalid token #{token}"
19
+ end
20
+
21
+ end
22
+
23
+
@@ -0,0 +1,18 @@
1
+ require "test_birst_command"
2
+
3
+ class Test_read_config < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def teardown
9
+ end
10
+
11
+ def test_read_config
12
+ Birst_Command::Config.read_config(File.join(File.dirname(__FILE__),"resources/config_test.json"))
13
+ assert_equal "name@myplace.com", Birst_Command::Config.options[:username], "Error with config file"
14
+ end
15
+
16
+ end
17
+
18
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'birst_command'
5
+ require 'test/unit'
6
+ require 'benchmark'
7
+
8
+ Birst_Command::Config.set_debug
9
+
10
+ include Birst_Command
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Birst_Command
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sterling Paramore
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: savon
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: httpclient
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
41
+ description: Ruby interface to Birst web API
42
+ email:
43
+ - gnilrets@gmail.com
44
+ executables:
45
+ - obfuscate_pwd.rb
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .bundle/config
50
+ - .gitignore
51
+ - .ruby-version
52
+ - Birst_Command.gemspec
53
+ - Gemfile
54
+ - LICENSE
55
+ - README.md
56
+ - Rakefile
57
+ - bin/obfuscate_pwd.rb
58
+ - config.json_template
59
+ - lib/birst_command.rb
60
+ - lib/birst_command/config.rb
61
+ - lib/birst_command/obfuscate.rb
62
+ - lib/birst_command/session.rb
63
+ - lib/birst_command/version.rb
64
+ - test/.gitignore
65
+ - test/config_test.json_template
66
+ - test/standard/resources/config_test.json
67
+ - test/standard/test_add_user_to_space.rb
68
+ - test/standard/test_command_helper.rb
69
+ - test/standard/test_copy_space.rb
70
+ - test/standard/test_deobfuscate.rb
71
+ - test/standard/test_list_spaces.rb
72
+ - test/standard/test_login.rb
73
+ - test/standard/test_read_config.rb
74
+ - test/test_birst_command.rb
75
+ homepage: https://github.com/gnilrets
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project: Birst_Command
95
+ rubygems_version: 2.2.2
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Birst Command
99
+ test_files:
100
+ - test/config_test.json_template
101
+ - test/standard/resources/config_test.json
102
+ - test/standard/test_add_user_to_space.rb
103
+ - test/standard/test_command_helper.rb
104
+ - test/standard/test_copy_space.rb
105
+ - test/standard/test_deobfuscate.rb
106
+ - test/standard/test_list_spaces.rb
107
+ - test/standard/test_login.rb
108
+ - test/standard/test_read_config.rb
109
+ - test/test_birst_command.rb