ccs 1.0.0.rc1 → 3.1.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
  SHA256:
3
- metadata.gz: 0efddd17f5cf6cc4dda4edc407ec58993d82d34d508132228a4af0f3a2ff216a
4
- data.tar.gz: 654cd5f1e367d4c6c7a251666015d2896051e6bc84734a483f90b2af04f713e6
3
+ metadata.gz: ce4380f6f1c426727a7147117ba50c7dc21866ec766ecf01083846e5340d8d79
4
+ data.tar.gz: 162d1b0bebdcbec23a1bb72b2c82d7ad4b6994c4ab6fc4258d1ebeebe29c61b9
5
5
  SHA512:
6
- metadata.gz: 19d2e3f9349f122a9fa05a6fd41ee24cc37bc08f06448236313e6236e82020bdfc1b1eefaa4160f0d30b5287420509f337880794484d89a7dc59b6ab446a6923
7
- data.tar.gz: 60e209b81064b9813907722cc81c53574ac9ac493a7c6c0dcdca162cc59c9fc5b0ddd277415cd931f7d735ba22084a65aa16c9d76705107fe05e9f14cae45e81
6
+ metadata.gz: 70e1cd7ac88384e75d62093429b4fa37a4b2aba6c6b3439e47c856653b2eac54c56b2e55d11281b2258ee0497a6e5008cc365b3f402ae3277e6612764af9e502
7
+ data.tar.gz: 8b580583449616952eedf65b13e7c893464cfb7fd3595ff2f238eaf933741211dad276df92d31008b54b7d0976ed727bc9a9471d109dc6d8697e3caa047e2f3c
@@ -0,0 +1,10 @@
1
+ ## 3.1.0 2020-11-23
2
+
3
+
4
+ ### Added
5
+
6
+ - `force` argument to overwrite remote documents when uploading (paweljw)
7
+ - YARD documentation (paweljw)
8
+
9
+
10
+ [Compare 3.0.0...3.1.0](https://github.com/occson/ccs/compare/3.0.0...3.1.0)
data/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  # CCS
2
2
 
3
+ Configuration control system
3
4
 
4
5
  ## Installation
5
6
 
6
7
  Add this line to your application's Gemfile:
7
8
 
8
- ```ruby
9
- gem 'ccs'
10
- ```
9
+ gem 'ccs'
11
10
 
12
11
  And then execute:
13
12
 
@@ -19,17 +18,80 @@ Or install it yourself as:
19
18
 
20
19
  ## Usage
21
20
 
21
+ ccs cp [OPTIONS] <(LocalPath|STDIN)|(CCSUri|Uri)> <(CCSUri|Uri)|(LocalPath|STDOUT)>
22
+
23
+ Options:
24
+ -a CCS_ACCESS_TOKEN, CCS Access Token
25
+ --access-token
26
+ -p CCS_PASSPHRASE, CCS Passphrase
27
+ --passphrase
28
+ -f, --[no-]force Overwrite remote documents when uploading
29
+
30
+
22
31
  ## Example
23
32
 
33
+ Download to STDOUT
34
+
35
+ ccs cp ccs://workspace-name/0.1.0/path/to/file.yml -
36
+ ccs cp http://host.tld:9292/workspace-name/0.1.0/path/to/file.yml -
37
+ ccs cp https://host.tld/workspace-name/0.1.0/path/to/file.yml -
38
+
39
+ Download to local file
40
+
41
+ ccs cp ccs://workspace-name/0.1.0/path/to/file.yml /local/path/to/file.yml
42
+
43
+ Upload local file
44
+
45
+ ccs cp /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml
46
+
47
+ Upload local file, overwriting remote document if any'
48
+
49
+ ccs cp --force /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml
50
+
51
+ Upload content from STDIN
52
+
53
+ echo "{ a: 1 }" | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml
54
+ cat /local/path/to/file.yml | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml
55
+
56
+ ## API
57
+
58
+ Upload
59
+
60
+ require 'ccs'
61
+
62
+ destination = 'ccs://workspace-name/0.1.0/path/to/file.yml'
63
+ access_token = ENV.fetch('CCS_ACCESS_TOKEN')
64
+ passphrase = 'MyPassphrase'
65
+ content = 'RAILS_ENV=production'
66
+
67
+ Ccs::Document.new(destination, access_token, passphrase).upload(content)
68
+
69
+ Download
70
+
71
+ require 'ccs'
72
+
73
+ source = 'ccs://workspace-name/0.1.0/path/to/file.yml'
74
+ access_token = ENV.fetch('CCS_ACCESS_TOKEN')
75
+ passphrase = 'MyPassphrase'
76
+
77
+ Ccs::Document.new(source, access_token, passphrase).download
78
+
24
79
  ## Development
25
80
 
26
81
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
27
82
 
28
83
  To install this gem onto your local machine, run `bin/rake install`. To release a new version, update the version number in `version.rb`, and then run `bin/rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
29
84
 
85
+ ## Documentation
86
+
87
+ Documentation for the code should be written in YARD format. It can be generated locally into the `doc` directory by running
88
+
89
+ bundle exec yard
90
+
91
+
30
92
  ## Contributing
31
93
 
32
- Bug reports and pull requests are welcome on GitHub at https://github.com/tkowalewski/ccs. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
94
+ Bug reports and pull requests are welcome on GitHub at https://github.com/occson/ccs. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
33
95
 
34
96
 
35
97
  ## License
data/exe/ccs CHANGED
@@ -9,62 +9,82 @@ require 'io/console'
9
9
 
10
10
  options = {
11
11
  'access_token' => ENV['CCS_ACCESS_TOKEN'],
12
- 'secret_token' => ENV['CCS_SECRET_TOKEN']
12
+ 'passphrase' => ENV['CCS_PASSPHRASE']
13
13
  }
14
14
 
15
- option_parser = OptionParser.new
16
- option_parser.banner = 'Usage: ccs [OPTIONS] <(LocalPath|STDIN)|(CCSUri|Uri)> <(CCSUri|Uri)|(LocalPath|STDOUT)>'
17
- option_parser.separator ''
18
- option_parser.separator 'Configuration Control System (CCS)'
19
- option_parser.separator ''
20
- option_parser.separator 'Options:'
15
+ option_parser = OptionParser.new do |option_parser|
16
+ option_parser.banner = 'Usage: ccs [COMMAND [OPTIONS]]'
21
17
 
22
- option_parser.on('-c CONFIGURATION', '--configuration CONFIGURATION', String, 'Path to configuration file') do |v|
23
- options['configuration'] = v
24
- end
18
+ option_parser.separator ''
19
+ option_parser.separator 'Configuration Control System (CCS)'
20
+ option_parser.separator ''
21
+ option_parser.separator 'Commands:'
22
+ option_parser.separator ' cp Copy'
25
23
 
26
- option_parser.on('-a CCS_ACCESS_TOKEN', '--access-token CCS_ACCESS_TOKEN', String, 'CCS Access Token') do |v|
27
- options['access_token'] = v
24
+ option_parser.separator ''
25
+ option_parser.separator format('Version: %<version>s', version: Ccs::VERSION)
28
26
  end
29
27
 
30
- option_parser.on('-s CCS_SECRET_TOKEN', '--secret-token CCS_SECRET_TOKEN', String, 'CCS Secret Token') do |v|
31
- options['secret_token'] = v
32
- end
28
+ case ARGV.shift
29
+ when 'cp'
30
+ option_parser = OptionParser.new do |option_parser|
31
+ option_parser.banner = 'Usage: ccs cp [OPTIONS] <(LocalPath|STDIN)|(CCSUri|Uri)> <(CCSUri|Uri)|(LocalPath|STDOUT)>'
32
+ option_parser.separator ''
33
+ option_parser.separator 'Configuration Control System (CCS) - Copy'
34
+ option_parser.separator ''
35
+ option_parser.separator 'Options:'
33
36
 
34
- option_parser.separator ''
35
- option_parser.separator 'Configure via environment variables'
36
- option_parser.separator ' CCS_ACCESS_TOKEN'
37
- option_parser.separator ' CCS_SECRET_TOKEN'
38
-
39
- option_parser.separator ''
40
- option_parser.separator 'Examples:'
41
- option_parser.separator ' Download to STDOUT'
42
- option_parser.separator ' ccs ccs://workspace-name/0.1.0/path/to/file.yml -'
43
- option_parser.separator ' ccs http://host.tld:9292/workspace-name/0.1.0/path/to/file.yml -'
44
- option_parser.separator ' ccs https://host.tld/workspace-name/0.1.0/path/to/file.yml -'
45
- option_parser.separator ' Download to local file'
46
- option_parser.separator ' ccs ccs://workspace-name/0.1.0/path/to/file.yml /local/path/to/file.yml'
47
- option_parser.separator ' Upload local file'
48
- option_parser.separator ' ccs /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml'
49
- option_parser.separator ' Upload content from STDIN'
50
- option_parser.separator ' echo "{ a: 1 }" | ccs - ccs://workspace-name/0.1.0/path/to/file.yml'
51
- option_parser.separator ' cat /local/path/to/file.yml | ccs - ccs://workspace-name/0.1.0/path/to/file.yml'
52
- option_parser.separator ''
53
-
54
- option_parser.separator format('Version: %<version>s', version: Ccs::VERSION)
55
-
56
- arguments = option_parser.parse!
57
-
58
- unless options.values.any?
59
- puts option_parser
60
- exit(1)
61
- end
37
+ option_parser.on('-a CCS_ACCESS_TOKEN', '--access-token CCS_ACCESS_TOKEN', String, 'CCS Access Token') do |v|
38
+ options['access_token'] = v
39
+ end
40
+
41
+ option_parser.on('-p CCS_PASSPHRASE', '--passphrase CCS_PASSPHRASE', String, 'CCS Passphrase') do |v|
42
+ options['passphrase'] = v
43
+ end
44
+
45
+ option_parser.on('-f', '--[no-]force', 'Overwrite remote documents when uploading') do |v|
46
+ options['force'] = v
47
+ end
62
48
 
63
- options = YAML.safe_load File.read(options.delete('configuration')) if options.key?('configuration')
49
+ option_parser.separator ''
50
+ option_parser.separator 'Configure via environment variables:'
51
+ option_parser.separator ' CCS_ACCESS_TOKEN'
52
+ option_parser.separator ' CCS_PASSPHRASE'
64
53
 
65
- raise OptionParser::MissingArgument, 'access_token' unless options['access_token']
66
- raise OptionParser::MissingArgument, 'secret_token' unless options['secret_token']
67
- raise OptionParser::MissingArgument, 'source' unless arguments.fetch(0, nil)
68
- raise OptionParser::MissingArgument, 'destination' unless arguments.fetch(1, nil)
54
+ option_parser.separator ''
55
+ option_parser.separator 'Examples:'
56
+ option_parser.separator ' Download to STDOUT'
57
+ option_parser.separator ' ccs cp ccs://workspace-name/0.1.0/path/to/file.yml -'
58
+ option_parser.separator ' ccs cp http://host.tld:9292/workspace-name/0.1.0/path/to/file.yml -'
59
+ option_parser.separator ' ccs cp https://host.tld/workspace-name/0.1.0/path/to/file.yml -'
60
+ option_parser.separator ' Download to local file'
61
+ option_parser.separator ' ccs cp ccs://workspace-name/0.1.0/path/to/file.yml /local/path/to/file.yml'
62
+ option_parser.separator ' Upload local file'
63
+ option_parser.separator ' ccs cp /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml'
64
+ option_parser.separator ' Upload local file, overwriting remote document if any'
65
+ option_parser.separator ' ccs cp --force /local/path/to/file.yml ccs://workspace-name/0.1.0/path/to/file.yml'
66
+ option_parser.separator ' Upload content from STDIN'
67
+ option_parser.separator ' echo "{ a: 1 }" | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml'
68
+ option_parser.separator ' cat /local/path/to/file.yml | ccs cp - ccs://workspace-name/0.1.0/path/to/file.yml'
69
+ option_parser.separator ''
69
70
 
70
- exit(1) unless Ccs::Application.new(arguments[0], arguments[1], options['access_token'], options['secret_token']).run
71
+ option_parser.separator format('Version: %<version>s', version: Ccs::VERSION)
72
+ end
73
+
74
+ arguments = option_parser.parse!
75
+
76
+ unless options.values.any?
77
+ puts option_parser
78
+ exit(1)
79
+ end
80
+
81
+ raise OptionParser::MissingArgument, 'access_token' unless options['access_token']
82
+ raise OptionParser::MissingArgument, 'passphrase' unless options['passphrase']
83
+ raise OptionParser::MissingArgument, 'source' unless arguments.fetch(0, nil)
84
+ raise OptionParser::MissingArgument, 'destination' unless arguments.fetch(1, nil)
85
+
86
+ exit(1) unless Ccs::Commands::Copy.new(arguments[0], arguments[1], options['access_token'], options['passphrase'], force: options.fetch('force', false)).call
87
+ else
88
+ puts option_parser
89
+ exit(1)
90
+ end
data/lib/ccs.rb CHANGED
@@ -11,7 +11,9 @@ require 'ccs/encrypter'
11
11
  require 'ccs/decrypter'
12
12
  require 'ccs/uploader'
13
13
  require 'ccs/downloader'
14
- require 'ccs/configuration_file'
15
- require 'ccs/application'
14
+ require 'ccs/document'
16
15
 
16
+ require 'ccs/commands/copy'
17
+
18
+ # Top level `Ccs` namespace.
17
19
  module Ccs; end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ccs
4
+ module Commands
5
+ # The copy command, responsible for copying a target to a destination, performing encryption
6
+ # and decryption as necessary.
7
+ #
8
+ # The target and destinations can be:
9
+ #
10
+ # - STDIN/STDOUT: a `-` sign is interpreted as these standard streams
11
+ #
12
+ # - The Occson server: strings beginning with `ccs://` or `http(s)://` are interpreted as such
13
+ #
14
+ # - local files: everything not matching the previous descriptions is assumed to
15
+ # be a path on the local system
16
+ class Copy
17
+ # Builds an instance of the Copy command.
18
+ #
19
+ # @param source [String] `-` for STDIN, an URI or a local file path
20
+ # @param destination [String] `-` for STDOUT, an URI or a local file path
21
+ # @param access_token [String] Occson access token
22
+ # @param passphrase [String] Passphrase used for encryption of the document
23
+ # @param force [Boolean] Whether to overwrite target document in Occson, if any. Default `false`.
24
+ def initialize(source, destination, access_token, passphrase, force: false)
25
+ @source = source
26
+ @destination = destination
27
+ @access_token = access_token
28
+ @passphrase = passphrase
29
+ @force = force
30
+ end
31
+
32
+ # Performs a transfer between locations - an upload if `@source` is local or STDIN,
33
+ # a download if `@source` is an URI.
34
+ #
35
+ # No guarantees are made about the return values of this method.
36
+ def call
37
+ download? ? download : upload
38
+ end
39
+
40
+ private
41
+
42
+ def download?
43
+ @source.match?(%r{\A(ccs|https?):\/\/})
44
+ end
45
+
46
+ def download
47
+ content = Document.new(@source, @access_token, @passphrase).download
48
+ return unless content
49
+
50
+ (@destination.eql?('-') ? STDOUT : File.new(@destination, 'w')).print content
51
+ end
52
+
53
+ def upload
54
+ content = @source.eql?('-') ? STDIN.read : File.read(@source)
55
+ Document.new(@destination, @access_token, @passphrase).upload(content, force: @force)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,12 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ccs
4
+ # Handles client-side decryption for documents.
5
+ #
6
+ # The decrypter uses AES-256 in CBC mode internally. A salt is
7
+ # expected in bytes 8..15, with ciphertext occupying the
8
+ # further bytes.
4
9
  class Decrypter
10
+ # Constructs a Decrypter instance with given passphrase and content.
11
+ #
12
+ # @example
13
+ # Ccs::Decrypter.new('the content passphrase', content)
14
+ #
15
+ # @param passphrase [String] Passphrase for content decryption
16
+ # @param content [String] Encrypted document content
5
17
  def initialize(passphrase, content)
6
18
  @passphrase = passphrase
7
19
  @content = content
8
20
  end
9
21
 
22
+ # Performs decryption, returning plaintext if passphrase matched.
23
+ #
24
+ # @return [String] Plaintext document content
10
25
  def call
11
26
  decryptor.pkcs5_keyivgen(@passphrase, ciphertext_salt, 1)
12
27
  result = decryptor.update(encrypted)
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ccs
4
+ # An abstraction for the Document concept. Simplifies building URLs,
5
+ # uploading and downloading contents. Abstracts away workspaces due to
6
+ # the use of access tokens in constructions.
7
+ class Document
8
+ # Constructs a Document instance from a given URI, access token and passphrase.
9
+ #
10
+ # @example
11
+ # uri = 'ccs://path/to/file.yml'
12
+ # access_token = 'f30b5450421362c9ca0b'
13
+ # passphrase = 'my document passphrase'
14
+ #
15
+ # Ccs::Document.new(uri, access_token, passphrase)
16
+ #
17
+ # @param uri [String] Document URI. Accepts `ccs://` as shorthand for Occson location.
18
+ # @param access_token [String] Occson access token.
19
+ # @param passphrase [String] Document passphrase, used in encryption and decryption.
20
+ def initialize(uri, access_token, passphrase)
21
+ @uri = build_uri(uri)
22
+ @access_token = access_token
23
+ @passphrase = passphrase
24
+ end
25
+
26
+ # Uploads the given plaintext `content` to target URI.
27
+ #
28
+ # @example
29
+ # document.upload('My example plaintext.')
30
+ #
31
+ # @param content [String] Plaintext to be encrypted and uploaded.
32
+ # @param force [Boolean] Whether to overwrite target document in Occson, if any. Default `false`.
33
+ def upload(content, force: false)
34
+ Uploader.new(@uri, content, @access_token, @passphrase, force: force).call
35
+ end
36
+
37
+ # Downloads the encrypted document at `@uri` and returns the plaintext
38
+ # contents (given that `@passphrase` matches).
39
+ #
40
+ # @example
41
+ # plaintext = document.download
42
+ #
43
+ # @return [String] Decrypted document contents
44
+ def download
45
+ Downloader.new(@uri, @access_token, @passphrase).call
46
+ end
47
+
48
+ private
49
+
50
+ def build_uri(uri)
51
+ URI uri.sub('ccs://', 'https://api.occson.com/')
52
+ end
53
+ end
54
+ end
@@ -1,30 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ccs
4
+ # Downloads and decrypts the document at given URI with given access token.
5
+ # Decryption occurs using given passphrase.
4
6
  class Downloader
5
- def initialize(uri, access_token, secret_token)
7
+ # Constructs a Downloader instance from a given URI, access token and passphrase.
8
+ #
9
+ # @example
10
+ # uri = 'ccs://path/to/file.yml'
11
+ # access_token = 'f30b5450421362c9ca0b'
12
+ # passphrase = 'my document passphrase'
13
+ #
14
+ # Ccs::Downloader.new(uri, access_token, passphrase)
15
+ #
16
+ # @param uri [String] Document URI. Accepts `ccs://` as shorthand for Occson location.
17
+ # @param access_token [String] Occson access token.
18
+ # @param passphrase [String] Document passphrase, used in encryption and decryption.
19
+ def initialize(uri, access_token, passphrase)
6
20
  @uri = uri
7
21
  @access_token = access_token
8
- @secret_token = secret_token
22
+ @passphrase = passphrase
9
23
  end
10
24
 
25
+ # Performs the download and decryption of document.
26
+ #
27
+ # @return [String|nil] Decrypted body of the document or `nil` in case the
28
+ # server did not respond with a `200` HTTP code.
11
29
  def call
12
30
  response = http.request(request)
13
31
  body = response.body
14
32
  return unless response.code.eql? '200'
15
33
  json = JSON.parse body
16
34
 
17
- Decrypter.new(@secret_token, json['encrypted_content']).call
35
+ Decrypter.new(@passphrase, json['encrypted_content']).call
18
36
  end
19
37
 
20
38
  private
21
39
 
22
40
  def http
23
- Net::HTTP.new(@uri.host, @uri.port)
41
+ @http ||= Net::HTTP.new(@uri.host, @uri.port).tap do |http|
42
+ http.use_ssl = @uri.scheme.eql?('https')
43
+ end
24
44
  end
25
45
 
26
46
  def request
27
- Net::HTTP::Get.new(@uri.path, headers)
47
+ Net::HTTP::Get.new(@uri.path, headers).tap do |request|
48
+ request["User-Agent"] = format('ccs/%s', Ccs::VERSION)
49
+ end
28
50
  end
29
51
 
30
52
  def headers
@@ -1,13 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ccs
4
+ # Encrypts the given content for transmission. Uses AES-256 in CBC
5
+ # mode internally, with salting.
4
6
  class Encrypter
7
+ # Constructs an Encrypter instance with given passphrase, content and salt.
8
+ # Salt _must_ be exactly 8 characters long.
9
+ #
10
+ # @example
11
+ # passphrase = 'my long document passphrase'
12
+ # content = 'very secret content'
13
+ # salt = '12345678'
14
+ #
15
+ # Ccs::Encrypter.new(passphrase, content, salt)
16
+ #
17
+ # @param passphrase [String] Document passphrase.
18
+ # @param content [String] Plaintext content to be encrypted.
19
+ # @param salt [String] Salt to reinforce the encryption, included in
20
+ # plaintext in the encrypted document.
5
21
  def initialize(passphrase, content, salt)
6
22
  @passphrase = passphrase
7
23
  @content = content
8
24
  @salt = salt
9
25
  end
10
26
 
27
+ # Performs the actual encryption, returning base64-encoded ciphertext.
28
+ #
29
+ # @return [String] base64-encoded ciphertext
11
30
  def call
12
31
  encryptor.pkcs5_keyivgen(@passphrase, @salt, 1)
13
32
  encrypted = encryptor.update(@content)
@@ -1,27 +1,51 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ccs
4
+ # Encrypts and uploads the document to Occson.
4
5
  class Uploader
5
- def initialize(uri, content, access_token, secret_token)
6
+ # Constructs an Uploader instance from a given URI, content, access token and passphrase.
7
+ #
8
+ # @example
9
+ # uri = 'ccs://path/to/file.yml'
10
+ # content = 'my very secret message'
11
+ # access_token = 'f30b5450421362c9ca0b'
12
+ # passphrase = 'my document passphrase'
13
+ #
14
+ # Ccs::Uploader.new(uri, access_token, passphrase)
15
+ #
16
+ # @param uri [String] Document URI. Accepts `ccs://` as shorthand for Occson location.
17
+ # @param content [String] Plaintext for encryption and upload.
18
+ # @param access_token [String] Occson access token.
19
+ # @param passphrase [String] Document passphrase, used in encryption and decryption.
20
+ # @param force [Boolean] Whether to overwrite target document in Occson, if any. Default `false`.
21
+ def initialize(uri, content, access_token, passphrase, force: false)
6
22
  @uri = uri
7
23
  @content = content
8
24
  @access_token = access_token
9
- @secret_token = secret_token
25
+ @passphrase = passphrase
26
+ @force = force.to_s
10
27
  end
11
28
 
29
+ # Performs the actual upload to server.
30
+ #
31
+ # @return [Boolean] `true` for a successful upload, `false` otherwise
12
32
  def call
13
- request.body = { encrypted_content: encrypted_content }.to_json
14
- http.request(request).code.eql? '201'
33
+ request.body = { encrypted_content: encrypted_content, force: @force }.to_json
34
+ %w[200 201].include?(http.request(request).code)
15
35
  end
16
36
 
17
37
  private
18
38
 
19
39
  def http
20
- Net::HTTP.new(@uri.host, @uri.port)
40
+ @http ||= Net::HTTP.new(@uri.host, @uri.port).tap do |http|
41
+ http.use_ssl = @uri.scheme.eql?('https')
42
+ end
21
43
  end
22
44
 
23
45
  def request
24
- @request ||= Net::HTTP::Post.new(@uri.path, headers)
46
+ @request ||= Net::HTTP::Post.new(@uri.path, headers).tap do |request|
47
+ request["User-Agent"] = format('ccs/%s', Ccs::VERSION)
48
+ end
25
49
  end
26
50
 
27
51
  def headers
@@ -32,7 +56,7 @@ module Ccs
32
56
  end
33
57
 
34
58
  def encrypted_content
35
- @encrypted_content ||= Encrypter.new(@secret_token, @content, salt).call
59
+ @encrypted_content ||= Encrypter.new(@passphrase, @content, salt).call
36
60
  end
37
61
 
38
62
  def salt
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ccs
4
- VERSION = '1.0.0.rc1'
4
+ # Ccs gem version definition
5
+ VERSION = '3.1.0'
5
6
  end
metadata CHANGED
@@ -1,43 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ccs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tkowalewski
8
+ - paweljw
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2018-03-28 00:00:00.000000000 Z
12
+ date: 2020-11-23 00:00:00.000000000 Z
12
13
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 1.16.1
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 1.16.1
27
14
  - !ruby/object:Gem::Dependency
28
15
  name: inch
29
16
  requirement: !ruby/object:Gem::Requirement
30
17
  requirements:
31
18
  - - "~>"
32
19
  - !ruby/object:Gem::Version
33
- version: 0.7.1
20
+ version: 0.8.0
34
21
  type: :development
35
22
  prerelease: false
36
23
  version_requirements: !ruby/object:Gem::Requirement
37
24
  requirements:
38
25
  - - "~>"
39
26
  - !ruby/object:Gem::Version
40
- version: 0.7.1
27
+ version: 0.8.0
41
28
  - !ruby/object:Gem::Dependency
42
29
  name: pry
43
30
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +45,14 @@ dependencies:
58
45
  requirements:
59
46
  - - "~>"
60
47
  - !ruby/object:Gem::Version
61
- version: 12.3.0
48
+ version: 13.0.1
62
49
  type: :development
63
50
  prerelease: false
64
51
  version_requirements: !ruby/object:Gem::Requirement
65
52
  requirements:
66
53
  - - "~>"
67
54
  - !ruby/object:Gem::Version
68
- version: 12.3.0
55
+ version: 13.0.1
69
56
  - !ruby/object:Gem::Dependency
70
57
  name: reek
71
58
  requirement: !ruby/object:Gem::Requirement
@@ -140,19 +127,20 @@ dependencies:
140
127
  name: yard
141
128
  requirement: !ruby/object:Gem::Requirement
142
129
  requirements:
143
- - - "~>"
130
+ - - ">="
144
131
  - !ruby/object:Gem::Version
145
- version: 0.8.7.5
132
+ version: 0.9.11
146
133
  type: :development
147
134
  prerelease: false
148
135
  version_requirements: !ruby/object:Gem::Requirement
149
136
  requirements:
150
- - - "~>"
137
+ - - ">="
151
138
  - !ruby/object:Gem::Version
152
- version: 0.8.7.5
139
+ version: 0.9.11
153
140
  description: ''
154
141
  email:
155
142
  - me@tkowalewski.pl
143
+ - p@steamshard.net
156
144
  executables:
157
145
  - ccs
158
146
  extensions: []
@@ -164,14 +152,14 @@ files:
164
152
  - README.md
165
153
  - exe/ccs
166
154
  - lib/ccs.rb
167
- - lib/ccs/application.rb
168
- - lib/ccs/configuration_file.rb
155
+ - lib/ccs/commands/copy.rb
169
156
  - lib/ccs/decrypter.rb
157
+ - lib/ccs/document.rb
170
158
  - lib/ccs/downloader.rb
171
159
  - lib/ccs/encrypter.rb
172
160
  - lib/ccs/uploader.rb
173
161
  - lib/ccs/version.rb
174
- homepage: https://github.com/tkowalewski/ccs
162
+ homepage: https://github.com/occson/ccs
175
163
  licenses:
176
164
  - MIT
177
165
  metadata: {}
@@ -186,12 +174,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
186
174
  version: '0'
187
175
  required_rubygems_version: !ruby/object:Gem::Requirement
188
176
  requirements:
189
- - - ">"
177
+ - - ">="
190
178
  - !ruby/object:Gem::Version
191
- version: 1.3.1
179
+ version: '0'
192
180
  requirements: []
193
- rubyforge_project:
194
- rubygems_version: 2.7.3
181
+ rubygems_version: 3.0.3
195
182
  signing_key:
196
183
  specification_version: 4
197
184
  summary: Configuration Control System (CCS)
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ccs
4
- class Application
5
- def initialize(source, destination, access_token, secret_token)
6
- @source = source
7
- @destination = destination
8
- @access_token = access_token
9
- @secret_token = secret_token
10
- end
11
-
12
- def run
13
- download? ? download : upload
14
- end
15
-
16
- private
17
-
18
- def download?
19
- @source.match?(%r{\A(ccs|https?):\/\/})
20
- end
21
-
22
- def download
23
- content = ConfigurationFile.new(@source, @access_token, @secret_token).download
24
- return unless content
25
-
26
- (@destination.eql?('-') ? STDOUT : File.new(@destination, 'w')).print content
27
- end
28
-
29
- def upload
30
- content = @source.eql?('-') ? STDIN.read : File.read(@source)
31
- ConfigurationFile.new(@destination, @access_token, @secret_token).upload(content)
32
- end
33
- end
34
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Ccs
4
- class ConfigurationFile
5
- def initialize(uri, access_token, secret_token)
6
- @uri = build_uri(uri)
7
- @access_token = access_token
8
- @secret_token = secret_token
9
- end
10
-
11
- def upload(content)
12
- Uploader.new(@uri, content, @access_token, @secret_token).call
13
- end
14
-
15
- def download
16
- Downloader.new(@uri, @access_token, @secret_token).call
17
- end
18
-
19
- private
20
-
21
- def build_uri(uri)
22
- URI uri.sub('ccs://', 'https://api.occson.com/')
23
- end
24
- end
25
- end