Birst_Command 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Birst_Command.gemspec +1 -0
- data/Gemfile +1 -0
- data/README.md +19 -17
- data/bin/birstcl +0 -18
- data/lib/birst_command.rb +1 -1
- data/lib/birst_command/session.rb +3 -1
- data/lib/birst_command/version.rb +1 -1
- data/test/standard/test_password.rb +4 -37
- metadata +16 -3
- data/lib/birst_command/password.rb +0 -66
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6bad6616cef05fab628640a4acabc9b7c219baf4
|
4
|
+
data.tar.gz: d4e2bf27651cf4ef20d1038b064ee8f7f4b83bbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b3d0ba0d5ad7a2609aefde09576f90fe927a3caaeba804967510cfce381271878069e9524d1e72502c6b777c61a84ffa9376771ba715888a35bbe5af81372e5f
|
7
|
+
data.tar.gz: fa825d4847ec8e2d6dc06b7af1992e6e3f352f030649e64135bb622f51a3d5d5e156b7d38e5fa7f104ed7daae657350ea70f1a8c3521504923042c2222f46077
|
data/Birst_Command.gemspec
CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.required_ruby_version = '~> 2'
|
18
18
|
s.add_runtime_dependency "savon", ["~> 2.0"]
|
19
19
|
s.add_runtime_dependency "httpclient", ["~> 2.3"]
|
20
|
+
s.add_runtime_dependency "envcrypt", ["~> 0.1"]
|
20
21
|
|
21
22
|
s.files = `git ls-files`.split("\n")
|
22
23
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
Birst_Command
|
2
2
|
====================
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/Birst_Command.svg)](http://badge.fury.io/rb/Birst_Command)
|
3
4
|
|
4
5
|
Birst Command is a Ruby gem that allows you to build Ruby scripts that
|
5
6
|
interface with the Birst Web API. It also comes with a simple command line
|
@@ -10,8 +11,8 @@ Birst user that needed to set up a very basic Ruby interface.
|
|
10
11
|
|
11
12
|
# Installation & Setup
|
12
13
|
|
13
|
-
**SPECIAL NOTE:** Password management has changed since version 0.
|
14
|
-
|
14
|
+
**SPECIAL NOTE:** Password management has changed since version 0.4.0.
|
15
|
+
Read below for details.
|
15
16
|
|
16
17
|
Prerequisites: Ruby > 2.0 and rubygems.
|
17
18
|
|
@@ -34,30 +35,26 @@ the username and password. (**Note**: do not use `login.bws.birst.com`
|
|
34
35
|
since it does not use an updated WSDL; a specific app server must be
|
35
36
|
specified). Since I have a strong aversion to storing passwords in
|
36
37
|
plaintext, the password in the config file needs to use and encrypted
|
37
|
-
password. Birst Command comes with a password encryptor
|
38
|
+
password. Birst Command comes bundled with a password encryptor
|
39
|
+
called [Envcrypt](https://github.com/gnilrets/envcrypt) that can be
|
38
40
|
executed via
|
39
41
|
|
40
42
|
````bash
|
41
|
-
$
|
43
|
+
$ envcrypt -s mypassword
|
42
44
|
````
|
43
45
|
|
44
46
|
which should give an output similar to
|
45
47
|
````
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
- Remove them as environment variables to generate new ones
|
50
|
-
BIRST_COMMAND_IV="3Nn26chRPkclusqTHePpig=="
|
51
|
-
BIRST_COMMAND_KEY="MWHa7gksYQaZTTq4snjyOnBDWUnKaVJq1VF4cv82MgA="
|
52
|
-
BIRST_COMMAND_SALT="KI//0xfSrX4mdSpiSp69BQ=="
|
53
|
-
...
|
54
|
-
Use this encrypted password in your .birstcl file: "JlCX9/RvHnGuWZWUcjTelg=="
|
48
|
+
Encrypted Secret: 2KwUMeJIqsjPWWF9Fw0I+w==
|
49
|
+
ENVCRYPT_KEY='V/V919RKnz8l2M002336bg==$ARoQfp/9pfv5kVN/ysRuStLuTWJFZhQF1f49xkHbcwQ=$YAjVhHOXlcagmZoFYgPWdQ=='
|
50
|
+
WARNING: It is critical that the key and encryption password be stored separately!
|
55
51
|
````
|
56
52
|
|
57
|
-
Copy and paste the encrypted password into the
|
58
|
-
also need to ensure that the
|
59
|
-
indicated above. If you're
|
60
|
-
can include these in your
|
53
|
+
Copy and paste the encrypted password (aka "secret') into the
|
54
|
+
`$HOME/.birstcl` config file. You will also need to ensure that the
|
55
|
+
`ENVCRYPT_KEY` environment variable is set as indicated above. If you're
|
56
|
+
running in a development environment, you can include these in your
|
57
|
+
bash `~/.profile` file.
|
61
58
|
|
62
59
|
# Usage - Birst command line tool
|
63
60
|
|
@@ -227,3 +224,8 @@ entirely consistent in its use of camelCase for arguments (e.g.,
|
|
227
224
|
`listUsersInSpace`). This inconsistency requires us to **submit
|
228
225
|
commands as snake_case and arguments as the camelCase that Birst
|
229
226
|
uses.**
|
227
|
+
|
228
|
+
# Changelog
|
229
|
+
|
230
|
+
* 0.5.0
|
231
|
+
* Migrated password handling to use Envcrypt
|
data/bin/birstcl
CHANGED
@@ -14,10 +14,6 @@ module BirstCL
|
|
14
14
|
exit
|
15
15
|
end
|
16
16
|
|
17
|
-
if @options[:encrypt_password]
|
18
|
-
encrypt_password(@options[:encrypt_password])
|
19
|
-
end
|
20
|
-
|
21
17
|
if @options[:command]
|
22
18
|
read_config_file
|
23
19
|
execute_command
|
@@ -44,11 +40,6 @@ module BirstCL
|
|
44
40
|
exit
|
45
41
|
end
|
46
42
|
|
47
|
-
@options[:encrypt_password] = nil
|
48
|
-
opts.on("-e","--encrypt_password <PASSWORD>","Generates an encrypted version of PASSWORD that needs to be placed in ~/.birstcl") do |opt|
|
49
|
-
@options[:encrypt_password] = opt
|
50
|
-
end
|
51
|
-
|
52
43
|
@options[:command] = nil
|
53
44
|
opts.on("-c","--command <COMMAND>","COMMAND is the snake_case Birst web API command") do |opt|
|
54
45
|
@options[:command] = opt
|
@@ -88,15 +79,6 @@ module BirstCL
|
|
88
79
|
Birst_Command::Config.read_config(@options[:config_full_path])
|
89
80
|
end
|
90
81
|
|
91
|
-
def encrypt_password(password)
|
92
|
-
Birst_Command::Password.generate_keys(verbose: true)
|
93
|
-
puts <<-EOF.unindent
|
94
|
-
...
|
95
|
-
Use this encrypted password in your .birstcl file: "#{Birst_Command::Password.encrypt(password)}"
|
96
|
-
EOF
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
82
|
def write_cookie_file(file_full_path)
|
101
83
|
return nil if file_full_path.nil?
|
102
84
|
File.open(file_full_path, 'w') {|f| f.write(Marshal.dump(@session_cookie)) }
|
data/lib/birst_command.rb
CHANGED
@@ -4,10 +4,10 @@ require 'openssl'
|
|
4
4
|
require 'base64'
|
5
5
|
require 'securerandom'
|
6
6
|
require 'json'
|
7
|
+
require 'envcrypt'
|
7
8
|
|
8
9
|
require 'birst_command/config'
|
9
10
|
require 'birst_command/core_additions'
|
10
11
|
require 'birst_command/version'
|
11
|
-
require 'birst_command/password'
|
12
12
|
require 'birst_command/session'
|
13
13
|
|
@@ -34,12 +34,14 @@ module Birst_Command
|
|
34
34
|
|
35
35
|
|
36
36
|
def login(use_cookie: nil)
|
37
|
+
crypt = Envcrypt::Envcrypter.new
|
38
|
+
|
37
39
|
@auth_cookies = use_cookie
|
38
40
|
@response = @client.call(:login,
|
39
41
|
cookies: @auth_cookies,
|
40
42
|
message: {
|
41
43
|
username: @options[:username],
|
42
|
-
password:
|
44
|
+
password: crypt.decrypt(@options[:password])
|
43
45
|
})
|
44
46
|
|
45
47
|
@auth_cookies = @response.http.cookies if @auth_cookies.nil?
|
@@ -3,52 +3,19 @@ require "test_birst_command"
|
|
3
3
|
class Test_password < Test::Unit::TestCase
|
4
4
|
|
5
5
|
def setup
|
6
|
-
ENV['
|
7
|
-
ENV['BIRST_COMMAND_KEY'] = "N589Xi0YzzkE+bRGwp3yaoVk/lneYsLHdFP+366hwcY="
|
8
|
-
ENV['BIRST_COMMAND_SALT'] = "AUkJj8QSmNW3QazpyNl7og=="
|
6
|
+
ENV['ENVCRYPT_KEY'] = '9Aqck/FZ0pCRkiw95VpxLw==$kxnYLOCo9qHDHHaTZM+fN73WVclDkRqO+uxSgzFzrpQ=$qoEtCm1BQWgc+WAxpotsrw=='
|
9
7
|
|
10
8
|
@password = "mysecretpass"
|
11
|
-
@encrypted = "
|
9
|
+
@encrypted = "MBTkxkMT8AbQupkOwtG9uQ=="
|
12
10
|
end
|
13
11
|
|
14
12
|
def teardown
|
15
13
|
end
|
16
14
|
|
17
|
-
def test_key_generation
|
18
|
-
ENV['BIRST_COMMAND_IV'] = nil
|
19
|
-
ENV['BIRST_COMMAND_KEY'] = nil
|
20
|
-
ENV['BIRST_COMMAND_SALT'] = nil
|
21
|
-
|
22
|
-
Password.generate_keys
|
23
|
-
|
24
|
-
encrypted = Password.encrypt(@password)
|
25
|
-
decrypted = Password.decrypt(encrypted)
|
26
|
-
|
27
|
-
assert_equal @password, decrypted, "Wrong decrypted password"
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
def test_decryption_failure
|
32
|
-
Password.generate_keys
|
33
|
-
|
34
|
-
encrypted = Password.encrypt(@password)
|
35
|
-
ENV['BIRST_COMMAND_SALT'] = SecureRandom.base64
|
36
|
-
|
37
|
-
assert_raise OpenSSL::Cipher::CipherError do
|
38
|
-
decrypted = Password.decrypt(encrypted)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
def test_encrypt
|
44
|
-
assert_equal @encrypted, Password.encrypt(@password), "Expecting encrypted password #{@encrypted}"
|
45
|
-
end
|
46
|
-
|
47
15
|
def test_decrypt
|
48
|
-
|
16
|
+
crypt = Envcrypt::Envcrypter.new
|
17
|
+
assert_equal @password, crypt.decrypt(@encrypted), "Wrong decrypted password"
|
49
18
|
end
|
50
|
-
|
51
|
-
|
52
19
|
end
|
53
20
|
|
54
21
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: Birst_Command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sterling Paramore
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: savon
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: envcrypt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
41
55
|
description: Ruby interface to Birst web API
|
42
56
|
email:
|
43
57
|
- gnilrets@gmail.com
|
@@ -60,7 +74,6 @@ files:
|
|
60
74
|
- lib/birst_command.rb
|
61
75
|
- lib/birst_command/config.rb
|
62
76
|
- lib/birst_command/core_additions.rb
|
63
|
-
- lib/birst_command/password.rb
|
64
77
|
- lib/birst_command/session.rb
|
65
78
|
- lib/birst_command/version.rb
|
66
79
|
- test/.gitignore
|
@@ -1,66 +0,0 @@
|
|
1
|
-
module Birst_Command
|
2
|
-
module Password
|
3
|
-
extend self
|
4
|
-
|
5
|
-
def generate_keys(verbose: false)
|
6
|
-
iv = ENV['BIRST_COMMAND_IV'] || SecureRandom.base64
|
7
|
-
key = ENV['BIRST_COMMAND_KEY'] || SecureRandom.base64(32)
|
8
|
-
salt = ENV['BIRST_COMMAND_SALT'] || SecureRandom.base64
|
9
|
-
|
10
|
-
if verbose
|
11
|
-
puts <<-EOF.unindent
|
12
|
-
Set these keys as environment variables
|
13
|
-
- Do not lose them or you will have to regenerate your password.
|
14
|
-
- Keep them secure, your password is compromised if these keys are compromised.
|
15
|
-
- Remove them as environment variables to generate new ones
|
16
|
-
BIRST_COMMAND_IV="#{iv}"
|
17
|
-
BIRST_COMMAND_KEY="#{key}"
|
18
|
-
BIRST_COMMAND_SALT="#{salt}"
|
19
|
-
EOF
|
20
|
-
end
|
21
|
-
|
22
|
-
ENV['BIRST_COMMAND_IV'] = iv
|
23
|
-
ENV['BIRST_COMMAND_KEY'] = key
|
24
|
-
ENV['BIRST_COMMAND_SALT'] = salt
|
25
|
-
end
|
26
|
-
|
27
|
-
# Generate a new cipher for encryption or decryption
|
28
|
-
def create_cipher(mode)
|
29
|
-
iv = ENV['BIRST_COMMAND_IV'] || SecureRandom.base64
|
30
|
-
key = ENV['BIRST_COMMAND_KEY'] || SecureRandom.base64(32)
|
31
|
-
salt = ENV['BIRST_COMMAND_SALT'] || SecureRandom.base64
|
32
|
-
|
33
|
-
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
|
34
|
-
cipher.send(mode)
|
35
|
-
cipher.iv = iv
|
36
|
-
|
37
|
-
digest = OpenSSL::Digest::SHA256.new
|
38
|
-
key_len = cipher.key_len
|
39
|
-
iter = 20000
|
40
|
-
cipher.key = OpenSSL::PKCS5.pbkdf2_hmac(key, salt, iter, key_len, digest)
|
41
|
-
cipher
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
# Returns a base64-obfuscated password to be stored in the config.json file
|
46
|
-
def encrypt(pwd)
|
47
|
-
cipher = create_cipher(:encrypt)
|
48
|
-
|
49
|
-
encrypted = cipher.update pwd
|
50
|
-
encrypted << cipher.final
|
51
|
-
|
52
|
-
Base64.encode64(encrypted).chomp
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
# Returns a plaintext password
|
57
|
-
def decrypt(encrypted_pwd)
|
58
|
-
cipher = create_cipher(:decrypt)
|
59
|
-
|
60
|
-
decrypted = cipher.update Base64.decode64(encrypted_pwd)
|
61
|
-
decrypted << cipher.final
|
62
|
-
|
63
|
-
decrypted
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|