travis-encrypt 0.0.1
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 +7 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +23 -0
- data/lib/travis/encrypt.rb +27 -0
- data/lib/travis/encrypt/common.rb +33 -0
- data/lib/travis/encrypt/decryptor.rb +49 -0
- data/lib/travis/encrypt/encryptor.rb +41 -0
- data/lib/travis/encrypt/helpers.rb +18 -0
- data/lib/travis/encrypt/helpers/active_record.rb +13 -0
- data/lib/travis/encrypt/helpers/common.rb +30 -0
- data/lib/travis/encrypt/helpers/sequel.rb +31 -0
- data/lib/travis/encrypt/version.rb +5 -0
- data/spec/encrypt_spec.rb +21 -0
- data/spec/helpers_spec.rb +45 -0
- data/spec/spec_helper.rb +1 -0
- data/travis-encrypt.gemspec +19 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3cc5b08f7b744a0d65048a30fbc106574ca09020
|
4
|
+
data.tar.gz: d305be5fa49e303584418c5f848f6a3a333808a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cd83823e74a711d52dd0e2631f32a0124a38bd6758eb39b76943b4a0f23db04ae8422637b2615f38fa606b4855679f89b1e8a59dd1f0cd24209e1983f772eda3
|
7
|
+
data.tar.gz: 7daf90258525aaadabb554da5ed37702117b02e756a98065a7f6125c69ee442be9b8d08971f57195c1236f6658f75f15fc714ee9bba2f37e5c40e9cda02c09f7
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.2.5)
|
5
|
+
rspec (3.3.0)
|
6
|
+
rspec-core (~> 3.3.0)
|
7
|
+
rspec-expectations (~> 3.3.0)
|
8
|
+
rspec-mocks (~> 3.3.0)
|
9
|
+
rspec-core (3.3.2)
|
10
|
+
rspec-support (~> 3.3.0)
|
11
|
+
rspec-expectations (3.3.1)
|
12
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
13
|
+
rspec-support (~> 3.3.0)
|
14
|
+
rspec-mocks (3.3.2)
|
15
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
16
|
+
rspec-support (~> 3.3.0)
|
17
|
+
rspec-support (3.3.0)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
rspec
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'base64'
|
3
|
+
require 'travis/encrypt/decryptor'
|
4
|
+
require 'travis/encrypt/encryptor'
|
5
|
+
require 'travis/encrypt/helpers'
|
6
|
+
|
7
|
+
module Travis
|
8
|
+
module Encrypt
|
9
|
+
PREFIX = '--ENCR--'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :key
|
13
|
+
|
14
|
+
def setup(config)
|
15
|
+
self.key = config[:key]
|
16
|
+
end
|
17
|
+
|
18
|
+
def encrypt(string, options)
|
19
|
+
Encryptor.new(string, { key: key }.merge(options)).apply
|
20
|
+
end
|
21
|
+
|
22
|
+
def decrypt(string, options)
|
23
|
+
Decryptor.new(string, { key: key }.merge(options)).apply
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Travis
|
2
|
+
module Encrypt
|
3
|
+
module Common
|
4
|
+
def create_aes(mode = :encrypt, key, iv)
|
5
|
+
aes = OpenSSL::Cipher::AES.new(256, :CBC)
|
6
|
+
aes.send(mode)
|
7
|
+
aes.key = key
|
8
|
+
aes.iv = iv
|
9
|
+
aes
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_iv
|
13
|
+
SecureRandom.hex(8)
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_iv(string, iv)
|
17
|
+
"#{string}#{iv}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def extract_iv(string)
|
21
|
+
[string[-16..-1], string[0..-17]]
|
22
|
+
end
|
23
|
+
|
24
|
+
def encode(str)
|
25
|
+
Base64.strict_encode64(str)
|
26
|
+
end
|
27
|
+
|
28
|
+
def decode(str)
|
29
|
+
Base64.strict_decode64(str)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'travis/encrypt/common'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Encrypt
|
5
|
+
class Decryptor
|
6
|
+
include Common
|
7
|
+
|
8
|
+
attr_reader :string, :key, :options
|
9
|
+
|
10
|
+
def initialize(string, options)
|
11
|
+
@string = string
|
12
|
+
@key = options[:key] || fail("Need to pass a key")
|
13
|
+
@options = options || {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def apply?
|
17
|
+
string && (!use_prefix? || prefix_used?)
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply
|
21
|
+
apply? ? decrypt : string
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def use_prefix?
|
27
|
+
!!options[:use_prefix]
|
28
|
+
end
|
29
|
+
|
30
|
+
def prefix_used?
|
31
|
+
string[0..7] == PREFIX
|
32
|
+
end
|
33
|
+
|
34
|
+
def decrypt
|
35
|
+
string = self.string
|
36
|
+
string = string[8..-1] if prefix_used?
|
37
|
+
decoded = decode(string.to_s)
|
38
|
+
iv, string = extract_iv(decoded)
|
39
|
+
|
40
|
+
# A nil iv most likely means that the decoded string was not encrypted
|
41
|
+
# to begin with, so we return the plain string.
|
42
|
+
return string if iv.nil?
|
43
|
+
|
44
|
+
aes = create_aes(:decrypt, key.to_s, iv)
|
45
|
+
aes.update(string) + aes.final
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'travis/encrypt/common'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Encrypt
|
5
|
+
class Encryptor
|
6
|
+
include Common
|
7
|
+
|
8
|
+
attr_reader :string, :key, :options
|
9
|
+
|
10
|
+
def initialize(string, options)
|
11
|
+
@string = string
|
12
|
+
@key = options[:key] || fail("Need to pass a key")
|
13
|
+
@options = options || {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def apply?
|
17
|
+
!!string && !string.empty? && !options[:disable] # TODO ask piotr
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply
|
21
|
+
apply? ? encrypt : string
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def encrypt
|
27
|
+
iv = create_iv
|
28
|
+
aes = create_aes(:encrypt, key.to_s, iv)
|
29
|
+
string = aes.update(self.string) + aes.final
|
30
|
+
string = add_iv(string, iv)
|
31
|
+
string = encode(string)
|
32
|
+
string = "#{PREFIX}#{string}" if use_prefix?
|
33
|
+
string
|
34
|
+
end
|
35
|
+
|
36
|
+
def use_prefix?
|
37
|
+
options.key?(:use_prefix) ? !!options[:use_prefix] : true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'travis/encrypt/helpers/active_record'
|
2
|
+
require 'travis/encrypt/helpers/sequel'
|
3
|
+
|
4
|
+
module Travis
|
5
|
+
module Encrypt
|
6
|
+
module Helpers
|
7
|
+
def encrypt(string, options = {})
|
8
|
+
options[:key] ||= Encrypt.key
|
9
|
+
Encrypt.encrypt(string, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def decrypt(string, options = {})
|
13
|
+
options[:key] ||= Encrypt.key
|
14
|
+
Encrypt.decrypt(string, options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Travis
|
2
|
+
module Encrypt
|
3
|
+
module Helpers
|
4
|
+
module Common
|
5
|
+
module ClassMethods
|
6
|
+
def attr_encrypted(*names)
|
7
|
+
options = names.last.is_a?(Hash) ? names.pop : {}
|
8
|
+
define_encrypted_accessors(names, options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def define_encrypted_accessors(names, options)
|
12
|
+
names.each do |name|
|
13
|
+
define_encrypted_accessor(name, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def define_encrypted_accessor(name, options)
|
18
|
+
define_method(name) do
|
19
|
+
Encrypt.decrypt(self[name], options)
|
20
|
+
end
|
21
|
+
|
22
|
+
define_method(:"#{name}=") do |string|
|
23
|
+
self[name] = Encrypt.encrypt(string, options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'travis/encrypt/helpers/common'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Encrypt
|
5
|
+
module Helpers
|
6
|
+
module Sequel
|
7
|
+
module ClassMethods
|
8
|
+
def attr_encrypted(*names)
|
9
|
+
options = names.last.is_a?(Hash) ? names.pop : {}
|
10
|
+
super
|
11
|
+
define_encrypted_values(names, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def define_encrypted_values(names, options)
|
15
|
+
define_method(:values) do
|
16
|
+
super().inject({}) do |values, (name, value)|
|
17
|
+
value = Encrypt.decrypt(value, options) if names.include?(name)
|
18
|
+
values.merge(name => value)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
base.extend(Common::ClassMethods)
|
26
|
+
base.extend(ClassMethods)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
describe Travis::Encrypt do
|
2
|
+
include described_class::Helpers
|
3
|
+
|
4
|
+
let(:string) { 'travis' }
|
5
|
+
let(:encrypted) { encrypt(string, options) }
|
6
|
+
let(:decrypted) { decrypt(encrypted, options) }
|
7
|
+
let(:options) { { key: 'abcd' * 8 } }
|
8
|
+
|
9
|
+
it 'can decrypt an encrypted string' do
|
10
|
+
expect(decrypted).to eql(string)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'prefixes the encrypted string by default' do
|
14
|
+
expect(encrypted[0..7]).to eql(Travis::Encrypt::PREFIX)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not prefix the encrypted string when opted out' do
|
18
|
+
options[:use_prefix] = false
|
19
|
+
expect(encrypted[0..7]).to_not eql(described_class::PREFIX)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe Travis::Encrypt::Helpers do
|
2
|
+
subject { const.new }
|
3
|
+
before { Travis::Encrypt.key = 'abcd' * 8 }
|
4
|
+
|
5
|
+
shared_examples_for 'attributes' do
|
6
|
+
it 'encrypts an attribute' do
|
7
|
+
subject.attr = 'bar'
|
8
|
+
expect(subject.to_h.values.first[0..7]).to eql(Travis::Encrypt::PREFIX)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'decrypts an encrypted attribute' do
|
12
|
+
subject.attr = 'bar'
|
13
|
+
expect(subject.attr).to eql('bar')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe described_class::ActiveRecord do
|
18
|
+
let(:const) do
|
19
|
+
Struct.new(:attr) do
|
20
|
+
include Travis::Encrypt::Helpers::ActiveRecord
|
21
|
+
attr_encrypted :attr
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
include_examples 'attributes'
|
26
|
+
end
|
27
|
+
|
28
|
+
describe described_class::Sequel do
|
29
|
+
let(:const) do
|
30
|
+
Struct.new(:attr) do
|
31
|
+
# Sequel's values method returns a hash of attributes
|
32
|
+
include Module.new { def values; to_h; end }
|
33
|
+
include Travis::Encrypt::Helpers::Sequel
|
34
|
+
attr_encrypted :attr
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
include_examples 'attributes'
|
39
|
+
|
40
|
+
it 'decrypts an encrypted value' do
|
41
|
+
subject.attr = 'bar'
|
42
|
+
expect(subject.values).to eql(attr: 'bar')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'travis/encrypt'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
4
|
+
require 'travis/encrypt/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "travis-encrypt"
|
8
|
+
s.version = Travis::Encrypt::VERSION
|
9
|
+
s.authors = ["Travis CI"]
|
10
|
+
s.email = "contact@travis-ci.org"
|
11
|
+
s.homepage = "https://github.com/travis-ci/travis-encrypt"
|
12
|
+
s.summary = "Travis CI encryption support"
|
13
|
+
s.description = "#{s.summary}."
|
14
|
+
s.license = "MIT"
|
15
|
+
|
16
|
+
s.files = Dir['{bin/**/*,lib/**/*,spec/**/*,[A-Z]*}']
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.require_path = 'lib'
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: travis-encrypt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Travis CI
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Travis CI encryption support.
|
14
|
+
email: contact@travis-ci.org
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- Gemfile
|
20
|
+
- Gemfile.lock
|
21
|
+
- lib/travis/encrypt.rb
|
22
|
+
- lib/travis/encrypt/common.rb
|
23
|
+
- lib/travis/encrypt/decryptor.rb
|
24
|
+
- lib/travis/encrypt/encryptor.rb
|
25
|
+
- lib/travis/encrypt/helpers.rb
|
26
|
+
- lib/travis/encrypt/helpers/active_record.rb
|
27
|
+
- lib/travis/encrypt/helpers/common.rb
|
28
|
+
- lib/travis/encrypt/helpers/sequel.rb
|
29
|
+
- lib/travis/encrypt/version.rb
|
30
|
+
- spec/encrypt_spec.rb
|
31
|
+
- spec/helpers_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
- travis-encrypt.gemspec
|
34
|
+
homepage: https://github.com/travis-ci/travis-encrypt
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata: {}
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubyforge_project:
|
54
|
+
rubygems_version: 2.4.5
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Travis CI encryption support
|
58
|
+
test_files: []
|
59
|
+
has_rdoc:
|