streetcreds 0.1.2 → 0.2.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
2
  SHA1:
3
- metadata.gz: d6b3156f5f57a91de79416f6a14ed92da63cfeb2
4
- data.tar.gz: 577f748d2637ecf56289967ef2bb282061b97479
3
+ metadata.gz: 0573e55f19dd3630b82109a083f349004e918ecb
4
+ data.tar.gz: 7b1de8a55c673746ffcbef42cfa49631484406e5
5
5
  SHA512:
6
- metadata.gz: bc941acb4211500dca4e8f3571d157ee1416b08c25d9e91e0e7b4394b47f9d6cf7ed5017181a9068ffabee9b2023706205a3e489d38a4b9fb21e01df923d1333
7
- data.tar.gz: f057015e492ea3818f0793b88c55708c4c9b9ebca0e2c8eee661f4035633d958ffd43de20fa62261719f086e5690ee415828a6e438544d8b433f2fb8998d7f96
6
+ metadata.gz: a7acd91f79ac3c1a2cce59706f80b8abade9d088f951caee78f6c4883630deeee8a7b9afe6e67282c0ee9f963783204dcf8bf41f0189fb1598479170ad292046
7
+ data.tar.gz: 8506e8b4cea0e388d30c913c22afde738412f9b83ed98a72ef5c997ce1a6e104c394454170ddf39aa9eb21d241af586eba16187fea04a9c168da0c7528e0efae
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in 1s.gemspec
4
3
  gemspec
@@ -1,20 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- streetcreds (0.1.1)
5
- colorize
4
+ streetcreds (0.2.0)
5
+ encrypted_strings
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- colorize (0.7.7)
10
+ byebug (9.0.6)
11
+ encrypted_strings (0.3.3)
12
+ rake (10.5.0)
11
13
 
12
14
  PLATFORMS
13
15
  ruby
14
16
 
15
17
  DEPENDENCIES
16
- bundler (~> 1.10)
18
+ bundler (~> 1.15)
19
+ byebug
20
+ rake (~> 10.0)
17
21
  streetcreds!
18
22
 
19
23
  BUNDLED WITH
20
- 1.10.6
24
+ 1.15.1
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 Wesley Boynton
3
+ Copyright (c) 2017 Wesley Boynton
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,38 +1,44 @@
1
1
  # StreetCreds
2
2
 
3
- StreetCreds is a little tiny library to handle reading/writing credentials for ruby apps. I wrote it mostly because I do this a lot, and I want to stop re-writing my own code. I'm sure someone else has done it, but my apps all already use my code, so this should work as a drop-in replacement.
3
+ This is a gem that manages encrypted YAML files that can be used to store credentials and stuff you might just not want to leave lying around on your system.
4
4
 
5
- I plan to add stuff like:
6
- - Safer (non plaintext) storage
7
- - Database-based storage
8
- - Password Generation
9
-
10
- It's not in rubygems yet.
5
+ It doesn't use a strong or unique IV or anything like that. It's not top-notch security. It's just a quick-and-dirty way to obfuscate things you might be using locally to enable your code to access resources, short of using a local deployment of a secret manager like Hashicorp Vault.
6
+
7
+ It uses ruby 2.0 hash-syntax for many of its methods, allowing you to leave some things un-filled and asking for them if it needs them. If you don't want your code being interrupted to ask for a password, provide one programatically.
8
+
9
+ This is a complete rewrite of StreetCreds 0.1 and is definitely not backwards-compatible. It's barely the same thing.
11
10
 
12
11
  ## Usage
13
12
 
14
- TODO
13
+ Use it like this:
14
+ ```ruby
15
+ # #convert_on_valid is false by default and will assume you want to encrypt a valid YAML file
16
+ # if it hasn't been encrypted already.
17
+ cf = StreetCreds::CredFile.new(filepath: '~/mycreds.yml', convert_on_valid: true)
15
18
 
16
- ## License
19
+ # Add a cred via code:
20
+ cf['github'] = {'username' => 'wwboynton', password: 'xxxxxxxxxxxxxx'}
21
+ # Worth noting, all your keys will be recursively symbolized. Hope that's okay.
22
+
23
+ # #inspect is overridden and will #inspect the internal hash.
24
+ # This will show all values, including passwords and sensitive data!
25
+ puts cf.inspect
17
26
 
18
- The MIT License (MIT)
27
+ # Save back to the file. This will always be encrypted.
28
+ cf.save
19
29
 
20
- Copyright (c) 2015 Wesley Boynton
30
+ # Decrypt a file in-place
31
+ StreetCreds::CredFile.decrypt_existing_file(filepath: '~/mycreds.yml')
32
+
33
+ # You can encrypt-in-place too, but you could also just use #convert_on_valid
34
+ StreetCreds::CredFile.encrypt_existing_file(filepath: '~/mycreds.yml')
35
+
36
+ ```
37
+
38
+ ## License
21
39
 
22
- Permission is hereby granted, free of charge, to any person obtaining a copy
23
- of this software and associated documentation files (the "Software"), to deal
24
- in the Software without restriction, including without limitation the rights
25
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26
- copies of the Software, and to permit persons to whom the Software is
27
- furnished to do so, subject to the following conditions:
40
+ It's MIT. Do whatever.
28
41
 
29
- The above copyright notice and this permission notice shall be included in
30
- all copies or substantial portions of the Software.
42
+ ## Contributing
31
43
 
32
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38
- THE SOFTWARE.
44
+ I guess you can PR if you really want to. I'd probably look at it.
@@ -1,101 +1,9 @@
1
- require 'streetcreds/version'
2
- require 'colorize'
3
-
4
- module StreetCreds
5
- class Credentials
6
- # rubocop:disable Style/PredicateName
7
-
8
- require 'singleton'
9
- include Singleton
10
- attr_accessor :credentials
11
-
12
- def initialize
13
- end
14
-
15
- def set_up(cred_file)
16
- @cred_file = cred_file
17
- @sample_file = "#{cred_file}.sample"
18
- check_dir
19
- check_file
20
- @credentials = YAML.load_file(@cred_file) || {}
21
- end
22
-
23
- def check_dir
24
- cred_path = get_cred_path
25
- unless File.exist?(cred_path)
26
- puts "Creating credentials directory at '#{cred_path}'"
27
- FileUtils.mkdir_p(cred_path)
28
- end
29
- end
30
-
31
- def check_file
32
- unless File.exist?(@cred_file)
33
- puts "There is no credentials.yml file at '#{@cred_file.yellow}'".red
34
- puts "Please fill out the sample file at '#{@sample_file.yellow}' and copy it to '#{@cred_file.yellow}'".red
35
- if !File.exist?(@cred_file) && !File.exist?(@sample_file)
36
- File.open(@sample_file, 'w') { |f| f.write(sample) }
37
- end
38
- raise StandardError
39
- end
40
- end
41
-
42
-
43
- def get_cred_path
44
- @cred_file.split('/')[0..-2].join('/')
45
- end
46
-
47
- def save
48
- File.open(@cred_file, 'w') { |f| f.write(@credentials.to_yaml) }
49
- end
50
-
51
- def [](key)
52
- @credentials[key]
53
- end
54
-
55
- def []=(key, val)
56
- @credentials[key] = val
57
- end
58
-
59
- def has_key?(key)
60
- @credentials.has_key?(key)
61
- end
62
-
63
- def self.has_key?(key)
64
- Credentials.instance.has_key?(key)
65
- end
66
-
67
- def self.[](key)
68
- Credentials.instance[key]
69
- end
70
-
71
- def self.[]=(key, val)
72
- Credentials.instance[key] = val
73
- end
74
-
75
- def self.save
76
- Credentials.instance.save
77
- end
78
-
79
- def self.credentials
80
- Credentials.instance.credentials
81
- end
82
-
83
- def sample
84
- <<EOS
85
- ---
86
- :google:
87
- :username:
88
- :password:
89
- :google_drive:
90
- :client_id:
91
- :client_secret:
92
- :github:
93
- :username:
94
- :password:
95
- :hipchat:
96
- :token:
97
- EOS
98
- end
99
- end
100
- end
101
-
1
+ require 'streetcred/version'
2
+ require 'streetcred/cred_file'
3
+ require 'encrypted_strings'
4
+ require 'streetcred/patches/openssl_cipher_patch'
5
+ require 'yaml'
6
+ require 'streetcred/patches/yaml_patch'
7
+ require 'fileutils'
8
+ require 'pp'
9
+ # require 'byebug'
@@ -0,0 +1,84 @@
1
+ module StreetCred
2
+ class CredFile
3
+ def self.encrypt_existing_file(filepath:)
4
+ filepath = full_path(filepath)
5
+ hash = YAML.load(File.open(filepath))
6
+ new(filepath: filepath, hash: hash)
7
+ end
8
+
9
+ def self.decrypt_existing_file(filepath:)
10
+ filepath = full_path(filepath)
11
+ decrypted_contents = new(filepath: filepath).decrypt_file
12
+ File.open(filepath, 'w+') { |f| f.write(decrypted_contents) }
13
+ end
14
+
15
+ def initialize(filepath:, hash: nil, convert_on_valid: false)
16
+ @filepath = self.class.full_path(filepath)
17
+ load_file(hash: hash, convert_on_valid: convert_on_valid)
18
+ end
19
+
20
+ def load_file(convert_on_valid:, hash: nil)
21
+ if hash.nil?
22
+ begin
23
+ file_contents = File.read(@filepath)
24
+ return @hash = {} if file_contents.empty?
25
+ @hash = YAMLHelper.load_if_valid(file_contents) if convert_on_valid
26
+ @hash = YAMLHelper.load_if_valid(decrypt_file) unless @hash
27
+ rescue Errno::ENOENT
28
+ @hash = {}
29
+ end
30
+ end
31
+ @hash = self.class.symbolize_keys(@hash)
32
+ end
33
+
34
+ def decrypt_file(contents: nil, password: nil)
35
+ contents = File.read(@filepath) unless contents
36
+ password = ask_password if password.nil?
37
+ contents.decrypt(:symmetric, :password => password)
38
+ end
39
+
40
+ def save
41
+ FileUtils.mkdir_p(File.dirname(@filepath))
42
+ yaml = self.class.symbolize_keys(@hash).to_yaml
43
+ if yaml.empty?
44
+ File.delete(@filepath)
45
+ else
46
+ encrypted_yaml = encrypt_file(contents: yaml)
47
+ File.open(@filepath, 'w+') { |f| f.write(encrypted_yaml) }
48
+ end
49
+ end
50
+
51
+ def encrypt_file(contents:, password: nil)
52
+ password = ask_password if password.nil?
53
+ contents.encrypt(:symmetric, :password => password)
54
+ end
55
+
56
+ def ask_password
57
+ return @password if @password
58
+ print "Password?\n> "
59
+ @password = $stdin.noecho(&:gets).chomp
60
+ puts ''
61
+ @password
62
+ end
63
+
64
+ def inspect
65
+ @hash.inspect
66
+ end
67
+
68
+ # Act like a hash
69
+ def method_missing(meth, *args)
70
+ @hash.send(meth, *args)
71
+ end
72
+
73
+ def self.full_path(filepath)
74
+ Pathname.new(filepath).expand_path.to_s
75
+ end
76
+
77
+ # Adapted from https://stackoverflow.com/a/8379653/5637619
78
+ def self.symbolize_keys(hash)
79
+ Hash[hash.map do |k, v|
80
+ [k.to_sym, (v.is_a?(Hash) ? symbolize_keys(v) : v)]
81
+ end]
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,12 @@
1
+ require 'encrypted_strings'
2
+
3
+ # I know monkey patches are bad, but this warning is annoying and the encrypted_strings guys haven't accepted that PR.
4
+ module EncryptedStrings
5
+ class SymmetricCipher
6
+ def build_cipher(type) #:nodoc:
7
+ cipher = OpenSSL::Cipher.new(algorithm).send(type)
8
+ cipher.pkcs5_keyivgen(password)
9
+ cipher
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ module YAMLHelper
2
+ def self.load_if_valid(str)
3
+ res = YAML.load(str)
4
+ return false unless res.is_a?(Hash)
5
+ res
6
+ # rescue Exception => e
7
+ # return false
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  module StreetCreds
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'streetcreds/version'
4
+ require "streetcreds/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "streetcreds"
@@ -9,24 +9,28 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Wesley Boynton"]
10
10
  spec.email = ["wes@boynton.io"]
11
11
 
12
- spec.summary = %q{Manage credentials with ease!}
13
- spec.homepage = "https://www.github.com/wwboynton/streetcreds"
12
+ spec.summary = %q{Dead-simple password-based encryption and decryption of some yaml configuration files}
14
13
  spec.license = "MIT"
15
14
 
16
- # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
17
- # delete this section to allow pushing this gem to any host.
18
- if spec.respond_to?(:metadata)
19
- spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
20
- else
21
- raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
- end
15
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
16
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
17
+ # if spec.respond_to?(:metadata)
18
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
19
+ # else
20
+ # raise "RubyGems 2.0 or newer is required to protect against " \
21
+ # "public gem pushes."
22
+ # end
23
23
 
24
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
- spec.bindir = "bin"
26
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
+ f.match(%r{^(test|spec|features)/})
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
29
  spec.require_paths = ["lib"]
28
30
 
29
- spec.add_runtime_dependency 'colorize'
31
+ spec.add_runtime_dependency "encrypted_strings"
30
32
 
31
- spec.add_development_dependency "bundler", "~> 1.10"
33
+ spec.add_development_dependency "bundler", "~> 1.15"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "byebug"
32
36
  end
metadata CHANGED
@@ -1,43 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: streetcreds
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wesley Boynton
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2015-11-06 00:00:00.000000000 Z
11
+ date: 2017-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: colorize
14
+ name: encrypted_strings
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.10'
33
+ version: '1.15'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.10'
40
+ version: '1.15'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
41
69
  description:
42
70
  email:
43
71
  - wes@boynton.io
@@ -45,37 +73,40 @@ executables: []
45
73
  extensions: []
46
74
  extra_rdoc_files: []
47
75
  files:
48
- - .gitignore
76
+ - ".gitignore"
49
77
  - Gemfile
50
78
  - Gemfile.lock
51
79
  - LICENSE.txt
52
80
  - README.md
53
81
  - lib/streetcreds.rb
82
+ - lib/streetcreds/cred_file.rb
83
+ - lib/streetcreds/patches/openssl_cipher_patch.rb
84
+ - lib/streetcreds/patches/yaml_patch.rb
54
85
  - lib/streetcreds/version.rb
55
86
  - streetcreds.gemspec
56
- homepage: https://www.github.com/wwboynton/streetcreds
87
+ homepage:
57
88
  licenses:
58
89
  - MIT
59
- metadata:
60
- allowed_push_host: 'TODO: Set to ''http://mygemserver.com'''
90
+ metadata: {}
61
91
  post_install_message:
62
92
  rdoc_options: []
63
93
  require_paths:
64
94
  - lib
65
95
  required_ruby_version: !ruby/object:Gem::Requirement
66
96
  requirements:
67
- - - '>='
97
+ - - ">="
68
98
  - !ruby/object:Gem::Version
69
99
  version: '0'
70
100
  required_rubygems_version: !ruby/object:Gem::Requirement
71
101
  requirements:
72
- - - '>='
102
+ - - ">="
73
103
  - !ruby/object:Gem::Version
74
104
  version: '0'
75
105
  requirements: []
76
106
  rubyforge_project:
77
- rubygems_version: 2.0.14
107
+ rubygems_version: 2.6.11
78
108
  signing_key:
79
109
  specification_version: 4
80
- summary: Manage credentials with ease!
110
+ summary: Dead-simple password-based encryption and decryption of some yaml configuration
111
+ files
81
112
  test_files: []