streetcreds 0.1.2 → 0.2.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
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: []