ccli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Error < StandardError
4
+ end
5
+
6
+ class SessionMissingError < Error
7
+ end
8
+
9
+ class UnauthorizedError < Error
10
+ end
11
+
12
+ class ForbiddenError < Error
13
+ end
14
+
15
+ class OpenshiftClientMissingError < Error
16
+ end
17
+
18
+ class OpenshiftClientNotLoggedInError < Error
19
+ end
20
+
21
+ class KubernetesClientMissingError < Error
22
+ end
23
+
24
+ class KubernetesClientNotLoggedInError < Error
25
+ end
26
+
27
+ class OpenshiftSecretNotFoundError < Error
28
+ end
29
+
30
+ class NoFolderSelectedError < Error
31
+ end
32
+
33
+ class CryptopusAccountNotFoundError < Error
34
+ end
35
+
36
+ class TeamNotFoundError < Error
37
+ end
38
+
39
+ class FolderNotFoundError < Error
40
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Account
4
+ attr_reader :id, :accountname, :username, :password, :type, :ose_secret
5
+ attr_accessor :folder
6
+
7
+ def initialize(accountname: nil, username: nil, password: nil,
8
+ ose_secret: nil, type: nil, id: nil)
9
+ @id = id
10
+ @accountname = accountname
11
+ @username = username
12
+ @password = password
13
+ @ose_secret = ose_secret
14
+ @type = type || 'credentials'
15
+ end
16
+
17
+ def to_json(*_args)
18
+ AccountSerializer.to_json(self)
19
+ end
20
+
21
+ def to_yaml
22
+ AccountSerializer.to_yaml(self)
23
+ end
24
+
25
+ def to_osesecret
26
+ AccountSerializer.to_osesecret(self)
27
+ end
28
+
29
+ class << self
30
+ def find(id)
31
+ AccountSerializer.from_json(CryptopusAdapter.new.get("accounts/#{id}"))
32
+ end
33
+
34
+ def find_by_name_and_folder_id(name, id)
35
+ Folder.find(id).accounts.find do |account|
36
+ account.accountname.downcase == name.downcase
37
+ end
38
+ end
39
+
40
+ def from_json(json)
41
+ AccountSerializer.from_json(json)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Folder
4
+ attr_reader :name, :id, :accounts
5
+
6
+ def initialize(name: nil, id: nil, accounts: [])
7
+ @name = name
8
+ @id = id
9
+ @accounts = accounts
10
+ end
11
+
12
+ class << self
13
+ def find(id)
14
+ json = JSON.parse(CryptopusAdapter.new.get("folders/#{id}"),
15
+ symbolize_names: true)
16
+ included = json[:included] || []
17
+ name = json[:data][:attributes][:name]
18
+ accounts = included.map do |record|
19
+ Account.from_json(record.to_json) if %w[account_ose_secrets
20
+ account_credentials].include? record[:type]
21
+ end.compact
22
+ Folder.new(id: id, name: name, accounts: accounts)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './ose_secret'
4
+
5
+ class K8SSecret < OSESecret
6
+ class << self
7
+ def all
8
+ K8SAdapter.new.fetch_all_secrets.map { |s| OSESecretSerializer.from_yaml(s) }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OSESecret
4
+ attr_reader :name, :ose_secret
5
+
6
+ def initialize(name, ose_secret)
7
+ @name = name
8
+ @ose_secret = ose_secret
9
+ end
10
+
11
+ def to_account
12
+ OSESecretSerializer.to_account(self)
13
+ end
14
+
15
+ def to_yaml
16
+ OSESecretSerializer.to_yaml(self)
17
+ end
18
+
19
+ class << self
20
+ def find_by_name(name)
21
+ OSESecretSerializer.from_yaml(OSEAdapter.new.fetch_secret(name))
22
+ end
23
+
24
+ def all
25
+ OSEAdapter.new.fetch_all_secrets.map { |s| OSESecretSerializer.from_yaml(s) }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Team
4
+ attr_reader :name, :id, :folders
5
+
6
+ def initialize(name: nil, folders: nil, id: nil)
7
+ @name = name
8
+ @folders = folders
9
+ @id = id
10
+ end
11
+
12
+ def render_list
13
+ TeamPresenter.render_list(self)
14
+ end
15
+
16
+ def folder_by_name(name)
17
+ folders.find do |folder|
18
+ folder.name.downcase.gsub(' ', '-') == name.downcase
19
+ end
20
+ end
21
+
22
+ class << self
23
+ def all
24
+ cryptopus_adapter = CryptopusAdapter.new
25
+ response = JSON.parse(cryptopus_adapter.get('teams'), symbolize_names: true)
26
+ response[:data].map do |team|
27
+ TeamSerializer.from_json(team.to_json, folders_json: included_folders(response))
28
+ end
29
+ end
30
+
31
+ def find_by_name(name)
32
+ Team.all.find do |team|
33
+ team.name.downcase.gsub(' ', '-') == name.downcase
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def included_folders(json)
40
+ json[:included].select do |folder|
41
+ folder[:type] == 'folders'
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TeamPresenter
4
+ class << self
5
+ def render_list(team)
6
+ team_name = team.name.downcase
7
+ despaced_team_name = team_name.gsub(' ', '-')
8
+ folder_rows = team.folders.map do |folder|
9
+ folder_name = folder.name.downcase
10
+ "#{folder_name} (cry use #{despaced_team_name}/#{folder_name.gsub(' ', '-')})"
11
+ end
12
+
13
+ team_name = "#{team_name} => "
14
+ joined_folder_rows = folder_rows.join("\n" + ' ' * team_name.length)
15
+ team_name + joined_folder_rows
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ class AccountSerializer
6
+ class << self
7
+ # rubocop:disable Metrics/MethodLength
8
+ def to_json(account)
9
+ {
10
+ data: {
11
+ type: 'accounts',
12
+ id: account.id,
13
+ attributes: {
14
+ accountname: account.accountname,
15
+ type: account.type,
16
+ cleartext_username: account.username,
17
+ cleartext_password: account.password,
18
+ ose_secret: account.ose_secret
19
+ },
20
+ relationships: {
21
+ folder: {
22
+ data: {
23
+ id: account.folder,
24
+ type: 'folders'
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }.compact.to_json
30
+ end
31
+ # rubocop:enable Metrics/MethodLength
32
+
33
+ def to_yaml(account)
34
+ { 'id' => account.id,
35
+ 'accountname' => account.accountname,
36
+ 'username' => account.username,
37
+ 'password' => account.password,
38
+ 'type' => account.type }.to_yaml
39
+ end
40
+
41
+ def from_json(json)
42
+ json = JSON.parse(json, symbolize_names: true)
43
+ data = json[:data] || json
44
+ attributes = data[:attributes]
45
+ Account.new(accountname: attributes[:accountname],
46
+ username: attributes[:cleartext_username],
47
+ password: attributes[:cleartext_password],
48
+ ose_secret: attributes[:ose_secret],
49
+ type: attributes[:type],
50
+ id: data[:id])
51
+ end
52
+
53
+ def to_osesecret(account)
54
+ OSESecret.new(account.accountname, account.ose_secret)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FolderSerializer
4
+ class << self
5
+ def from_json(json)
6
+ json = JSON.parse(json, symbolize_names: true)
7
+ data = json[:data] || json
8
+ attributes = data[:attributes]
9
+ Folder.new(name: attributes[:name], id: data[:id])
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'psych'
4
+
5
+ class OSESecretSerializer
6
+ class << self
7
+ def from_yaml(yaml)
8
+ secret_hash = Psych.load(yaml, symbolize_names: true)
9
+ OSESecret.new(secret_hash.dig(:metadata, :name), yaml)
10
+ end
11
+
12
+ def to_account(secret)
13
+ Account.new(accountname: secret.name, ose_secret: secret.ose_secret, type: 'ose_secret')
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TeamSerializer
4
+ class << self
5
+ def from_json(json, folders_json: [])
6
+ json = JSON.parse(json, symbolize_names: true)
7
+ data = json[:data] || json
8
+ attributes = data[:attributes]
9
+ folder_ids = data[:relationships][:folders][:data].map { |folder| folder[:id] }
10
+ folders = folders_json.map do |folder|
11
+ FolderSerializer.from_json(folder.to_json) if folder_ids.include?(folder[:id])
12
+ end.compact
13
+ Team.new(name: attributes[:name],
14
+ folders: folders,
15
+ id: data[:id])
16
+ end
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ccli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nils Rauch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-10-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.5'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.5.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.5'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 4.5.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: tty-command
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: tty-exit
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: tty-logger
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ description:
76
+ email: rauch@puzzle.ch
77
+ executables:
78
+ - cry
79
+ extensions: []
80
+ extra_rdoc_files: []
81
+ files:
82
+ - ".rubocop.yml"
83
+ - ".travis.yml"
84
+ - Gemfile
85
+ - Gemfile.lock
86
+ - README.md
87
+ - bin/cry
88
+ - ccli.gemspec
89
+ - lib/adapters/cluster_secret_adapter.rb
90
+ - lib/adapters/cryptopus_adapter.rb
91
+ - lib/adapters/k8s_adapter.rb
92
+ - lib/adapters/ose_adapter.rb
93
+ - lib/adapters/session_adapter.rb
94
+ - lib/cli.rb
95
+ - lib/errors.rb
96
+ - lib/models/account.rb
97
+ - lib/models/folder.rb
98
+ - lib/models/k8s_secret.rb
99
+ - lib/models/ose_secret.rb
100
+ - lib/models/team.rb
101
+ - lib/presenters/team_presenter.rb
102
+ - lib/serializers/account_serializer.rb
103
+ - lib/serializers/folder_serializer.rb
104
+ - lib/serializers/ose_secret_serializer.rb
105
+ - lib/serializers/team_serializer.rb
106
+ homepage:
107
+ licenses: []
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '2.0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.7.9
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Command line client for the opensource password manager Cryptopus
129
+ test_files: []