cabal-api 0.2.2 → 0.2.3

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
- SHA1:
3
- metadata.gz: cd02a01c7d3ca61dc9abe5a212a02490d8d3cf5c
4
- data.tar.gz: 1d0971bd27184290b814153df1329274eafe6109
2
+ SHA256:
3
+ metadata.gz: 24c70d80c8dd38a65574f04cbc77bdae38614fe2e3105b0a842240c29f3b7089
4
+ data.tar.gz: dcda1995610094348fd395abf20b540d1bd2e075327d05224e655bc908c269ff
5
5
  SHA512:
6
- metadata.gz: adcc708a3dde3f62f4e4bbaa57d6b4f71a51529d981e439f6350da4f6e803dba58b3182ddedf0efff585d915a5f7c55f75be7f987ede89e33eeba5402626da70
7
- data.tar.gz: 84b8cc2bcb70e489f9bd8979a67906a7aacd1cf1492c91dc041608499e31352a4a522c4268c522040ef01c695dcf63e6a38ab026940e9b3c8daba61eca7fab16
6
+ metadata.gz: dc299c1679cadc10822a03033ce5c1c2ffbda45bd02511ffbf284be2cc67057f56f99123cace6e81735e6fa0309559c7f51d42994241733bc2d568e90bd11329
7
+ data.tar.gz: 88352f6445427c63c24fdda7d994ac0098d40f2f11bdc2bb2b0a74d62dc034460c0b8f17da21f2ec4f1a0de9b5fa26a36b810cec68407db7d9c30c6bc7b3663f
data/Dockerfile ADDED
@@ -0,0 +1,16 @@
1
+ FROM ruby:2.5.3
2
+
3
+ RUN apt-get update && apt-get install -y \
4
+ build-essential \
5
+ wamerican \
6
+ vim
7
+
8
+ RUN mkdir -p /app
9
+ WORKDIR /app
10
+
11
+ COPY . ./
12
+ RUN gem install bundler && bundle install
13
+
14
+ EXPOSE 3000
15
+
16
+ CMD ["/bin/bash"]
data/cabal-api.gemspec CHANGED
@@ -25,13 +25,12 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "rspec", '~> 3.3'
26
26
  spec.add_development_dependency "factis", '~> 1.0'
27
27
  spec.add_development_dependency "simplecov", '~> 0.10'
28
- spec.add_development_dependency "redis"
29
- spec.add_development_dependency "database_cleaner"
30
28
  spec.add_development_dependency "yard", "~> 0.8.7"
31
29
  spec.add_runtime_dependency "cabal-util", '~> 0.1'
32
- spec.add_runtime_dependency "grape", '~> 0.13'
33
- spec.add_runtime_dependency "ohm"
34
- spec.add_runtime_dependency "ohm-contrib"
35
- spec.add_runtime_dependency "bcrypt"
36
- spec.add_runtime_dependency "sshkey"
30
+ spec.add_runtime_dependency "grape", '~> 1.2'
31
+ spec.add_runtime_dependency "bcrypt", '~> 3.1'
32
+ spec.add_runtime_dependency "sshkey", '~> 1.9'
33
+ spec.add_runtime_dependency 'sekrat', '~> 1.0.0'
34
+ spec.add_runtime_dependency 'sekrat-crypter-aes', '~> 1.0.0'
35
+ spec.add_runtime_dependency 'dry-struct', '~> 0.6.0'
37
36
  end
@@ -0,0 +1,5 @@
1
+ app:
2
+ build: .
3
+ command: /bin/bash
4
+ volumes:
5
+ - .:/app
data/lib/cabal/api.rb CHANGED
@@ -1,11 +1,21 @@
1
- require 'ohm'
2
1
  require 'cabal/api/version'
3
2
  require 'cabal/api/base'
4
- require 'cabal/api/cluster'
5
- require 'cabal/api/user'
3
+ require 'cabal/api/cluster_service'
4
+ require 'cabal/api/user_service'
5
+ require 'sekrat'
6
6
 
7
7
  module Cabal
8
- module Api
9
- Ohm.redis = Redic.new(ENV['REDIS_URL'] || 'redis://localhost:6379')
8
+ module API
9
+ STORAGE = {
10
+ private: Sekrat::Warehouse::Memory.new,
11
+ public: Sekrat::Warehouse::Memory.new,
12
+ users: Sekrat::Warehouse::Memory.new,
13
+ access_keys: Sekrat::Warehouse::Memory.new,
14
+ secret_keys: Sekrat::Warehouse::Memory.new,
15
+ }
16
+
17
+ def cluster_service
18
+ @cluster_service ||= ClusterService.new
19
+ end
10
20
  end
11
21
  end
@@ -0,0 +1,71 @@
1
+ require 'sshkey'
2
+ require 'cabal/util'
3
+ require 'sekrat'
4
+ require 'sekrat/crypter/aes'
5
+
6
+ module Cabal
7
+ module API
8
+ class ClusterService
9
+ attr_accessor :public_keys, :private_keys
10
+
11
+ def initialize(public_warehouse: STORAGE[:public], private_warehouse: STORAGE[:private])
12
+ @public_keys = Sekrat.manager(warehouse: public_warehouse)
13
+
14
+ @private_keys = Sekrat.manager(warehouse: private_warehouse, crypter: Sekrat::Crypter::Aes)
15
+ end
16
+
17
+ def create(name)
18
+ sshkey = SSHKey.generate(
19
+ type: 'RSA',
20
+ bits: 2048,
21
+ comment: "#{name}-cabal"
22
+ )
23
+
24
+ write_public_key(name, sshkey) && write_private_key(name, sshkey)
25
+ end
26
+
27
+ def names
28
+ public_keys.ids
29
+ end
30
+
31
+ def public_key(name)
32
+ begin
33
+ public_keys.get(name, name)
34
+ rescue
35
+ nil
36
+ end
37
+ end
38
+
39
+ def private_key(name)
40
+ begin
41
+ private_keys.get(name, public_key(name))
42
+ rescue
43
+ nil
44
+ end
45
+ end
46
+
47
+ private
48
+ def write_public_key(name, key)
49
+ begin
50
+ public_keys.put(name, name, key.ssh_public_key)
51
+ true
52
+ rescue
53
+ return false
54
+ end
55
+ end
56
+
57
+ def write_private_key(name, key)
58
+ begin
59
+ private_keys.put(
60
+ name,
61
+ key.ssh_public_key,
62
+ key.private_key
63
+ )
64
+ true
65
+ rescue
66
+ false
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,4 +1,4 @@
1
- require 'cabal/api/user'
1
+ require 'cabal/api/common/services'
2
2
 
3
3
  module Cabal
4
4
  module API
@@ -6,11 +6,15 @@ module Cabal
6
6
  module Authenticated
7
7
  def self.included(base)
8
8
  base.class_eval do
9
+ include Cabal::API::Common::Services
10
+
9
11
  helpers do
10
12
  def current_user
11
13
  authorization = headers['Authorization'].to_s
12
14
  access_key, signature = authorization.split(':')
13
- user = Cabal::API::User.find(access_key: access_key).first
15
+
16
+ user = user_service.by_access_key(access_key)
17
+
14
18
  if user && user.authenticated_with?(signature)
15
19
  user
16
20
  else
@@ -4,7 +4,7 @@ module Cabal
4
4
  module Mistakes
5
5
  def self.included(base)
6
6
  base.class_eval do
7
- error_formatter :txt, ->(message, backtrace, options, env) {
7
+ error_formatter :txt, ->(message, backtrace, options, env, original_exception) {
8
8
  message[:message]
9
9
  }
10
10
 
@@ -1,8 +1,9 @@
1
1
  require 'cabal/util'
2
- require 'cabal/api/cluster'
2
+ require 'cabal/api'
3
3
  require 'cabal/api/user'
4
4
  require 'cabal/api/common/authenticated'
5
5
  require 'cabal/api/common/mistakes'
6
+ require 'cabal/api/common/services'
6
7
 
7
8
  module Cabal
8
9
  module API
@@ -12,6 +13,7 @@ module Cabal
12
13
  base.class_eval do
13
14
  include Cabal::API::Common::Authenticated
14
15
  include Cabal::API::Common::Mistakes
16
+ include Cabal::API::Common::Services
15
17
 
16
18
  formatter :txt, ->(object, env) {
17
19
  object[:private_ssh_key]
@@ -32,13 +34,13 @@ module Cabal
32
34
  authenticate!
33
35
 
34
36
  cluster_name = Cabal::Util.normalize(params[:name])
35
- cluster = Cabal::API::Cluster.find(name: cluster_name).first
37
+ key = cluster_service.private_key(cluster_name)
36
38
 
37
- error_if_not_found!(cluster, cluster_name)
39
+ error_if_not_found!(key, cluster_name)
38
40
 
39
41
  {
40
- name: cluster.name,
41
- private_ssh_key: cluster.private_key
42
+ name: cluster_name,
43
+ private_ssh_key: key
42
44
  }
43
45
  end
44
46
  end
@@ -1,5 +1,6 @@
1
1
  require 'cabal/util'
2
- require 'cabal/api/cluster'
2
+ require 'cabal/api'
3
+ require 'cabal/api/common/services'
3
4
 
4
5
  module Cabal
5
6
  module API
@@ -7,15 +8,20 @@ module Cabal
7
8
  module PublicKey
8
9
  def self.included(base)
9
10
  base.class_eval do
11
+ include Cabal::API::Common::Services
12
+
10
13
  formatter :txt, ->(object, env) {
11
14
  object[:public_ssh_key]
12
15
  }
13
16
 
14
17
  get '/key/:name' do
15
- cluster = Cabal::API::Cluster.by_cluster_name(params[:name])
18
+ name = Cabal::Util.normalize(params[:name])
19
+ cluster_service.create(name) unless cluster_service.names.include?(name)
20
+ key = cluster_service.public_key(name)
21
+
16
22
  {
17
- name: cluster.name,
18
- public_ssh_key: cluster.public_key
23
+ name: name,
24
+ public_ssh_key: key
19
25
  }
20
26
  end
21
27
  end
@@ -0,0 +1,30 @@
1
+ require 'cabal/api'
2
+
3
+ module Cabal
4
+ module API
5
+ module Common
6
+ module Services
7
+ def self.included(base)
8
+ base.class_eval do
9
+ helpers do
10
+ def cluster_service
11
+ @cluster_service ||= ClusterService.new(
12
+ public_warehouse: STORAGE[:public],
13
+ private_warehouse: STORAGE[:private]
14
+ )
15
+ end
16
+
17
+ def user_service
18
+ @user_service ||= UserService.new(
19
+ user_warehouse: STORAGE[:users],
20
+ access_key_warehouse: STORAGE[:access_keys],
21
+ secret_key_warehouse: STORAGE[:secret_keys]
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ require 'dry-types'
2
+
3
+ module Cabal
4
+ module API
5
+ module Types
6
+ include Dry::Types.module
7
+ end
8
+ end
9
+ end
@@ -1,49 +1,28 @@
1
- require 'ohm'
2
- require 'ohm/contrib'
3
1
  require 'bcrypt'
2
+ require 'dry-struct'
4
3
  require 'securerandom'
4
+ require 'cabal/api/types'
5
5
 
6
6
  module Cabal
7
7
  module API
8
- class User < Ohm::Model
9
- include Ohm::Callbacks
8
+ class User < Dry::Struct
9
+ transform_keys(&:to_sym)
10
10
 
11
- # The secret key should not be saved plain, but we want to access it
12
- # immediately after creation
13
- attr_accessor :secret_key
11
+ attribute :email, Types::Strict::String
12
+ attribute :access_key, Types::Strict::String
13
+ attribute :secret_key, Types::Strict::String.default('')
14
+ attribute :crypted_secret_key, Types::Strict::String.default('')
15
+ attribute :created_at, Types::JSON::Time
14
16
 
15
- attribute :email
16
- attribute :access_key
17
- attribute :crypted_secret_key
18
-
19
- # Enable lookups via either the user's email or their access key.
20
- index :email
21
- index :access_key
22
-
23
- # Ensure that email and access keys are unique
24
- unique :email
25
- unique :access_key
26
-
27
- def before_create
28
- set_access_key
29
- set_secret_key
17
+ def crypto_key
18
+ "#{email}::#{created_at}::#{access_key}"
30
19
  end
31
20
 
32
21
  def authenticated_with?(secret_key)
33
- return false unless crypted_secret_key
22
+ return false unless crypted_secret_key.length > 0
34
23
 
35
24
  BCrypt::Password.new(crypted_secret_key) == secret_key
36
25
  end
37
-
38
- private
39
- def set_access_key
40
- self.access_key = SecureRandom.hex(16)
41
- end
42
-
43
- def set_secret_key
44
- self.secret_key = SecureRandom.hex(32)
45
- self.crypted_secret_key = BCrypt::Password.create(secret_key)
46
- end
47
26
  end
48
27
  end
49
28
  end
@@ -0,0 +1,115 @@
1
+ require 'bcrypt'
2
+ require 'cabal/api/user'
3
+ require 'json'
4
+ require 'sekrat'
5
+ require 'sekrat/crypter/aes'
6
+ require 'sekrat/crypter/passthrough'
7
+
8
+ module Cabal
9
+ module API
10
+ class UserService
11
+ attr_reader :users, :access_keys, :secret_keys
12
+
13
+ def initialize(user_warehouse: STORAGE[:users], access_key_warehouse: STORAGE[:access_keys], secret_key_warehouse: STORAGE[:secret_keys])
14
+ passthrough = Sekrat::Crypter::Passthrough.new
15
+
16
+ @users = Sekrat.manager(
17
+ warehouse: user_warehouse,
18
+ crypter: passthrough
19
+ )
20
+
21
+ @access_keys = Sekrat.manager(
22
+ warehouse: access_key_warehouse,
23
+ crypter: passthrough
24
+ )
25
+
26
+ @secret_keys = Sekrat.manager(
27
+ warehouse: secret_key_warehouse,
28
+ crypter: Sekrat::Crypter::Aes
29
+ )
30
+ end
31
+
32
+ def create(email)
33
+ secret_key = SecureRandom.hex(32)
34
+
35
+ User.new(
36
+ email: email,
37
+ access_key: SecureRandom.hex(16),
38
+ secret_key: secret_key,
39
+ crypted_secret_key: BCrypt::Password.create(secret_key).to_s,
40
+ created_at: Time.now.utc
41
+ ).tap do |user|
42
+ return nil unless write_user(user) &&
43
+ write_access_key(user) &&
44
+ write_secret_key(user)
45
+ end
46
+ end
47
+
48
+ def list
49
+ users.ids.sort
50
+ end
51
+
52
+ def by_email(email)
53
+ user = begin
54
+ User.new(JSON.load(users.get(email, email)))
55
+ rescue
56
+ return nil
57
+ end
58
+
59
+ crypted_secret_key = begin
60
+ secret_keys.get(user.access_key, user.crypto_key)
61
+ rescue
62
+ return nil
63
+ end
64
+
65
+ user.new(crypted_secret_key: crypted_secret_key)
66
+ end
67
+
68
+ def by_access_key(access_key)
69
+ email = begin
70
+ access_keys.get(access_key, access_key)
71
+ rescue
72
+ return nil
73
+ end
74
+
75
+ by_email(email)
76
+ end
77
+
78
+ private
79
+ def write_user(user)
80
+ begin
81
+ users.put(
82
+ user.email,
83
+ user.email,
84
+ {
85
+ email: user.email,
86
+ access_key: user.access_key,
87
+ created_at: user.created_at
88
+ }.to_json
89
+ )
90
+ true
91
+ rescue
92
+ false
93
+ end
94
+ end
95
+
96
+ def write_access_key(user)
97
+ begin
98
+ access_keys.put(user.access_key, user.access_key, user.email)
99
+ true
100
+ rescue
101
+ false
102
+ end
103
+ end
104
+
105
+ def write_secret_key(user)
106
+ begin
107
+ secret_keys.put(user.access_key, user.crypto_key, user.crypted_secret_key)
108
+ true
109
+ rescue
110
+ false
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -1,6 +1,6 @@
1
1
  require 'grape'
2
2
  require 'cabal/util'
3
- require 'cabal/api/cluster'
3
+ require 'cabal/api/cluster_service'
4
4
  require 'cabal/api/user'
5
5
  require 'cabal/api/common/authenticated'
6
6
  require 'cabal/api/common/mistakes'
@@ -13,16 +13,14 @@ module Cabal
13
13
  include Cabal::API::Common::Mistakes
14
14
 
15
15
  formatter :txt, ->(object, env) {
16
- object.map {|cluster| cluster[:name]}.join("\n")
16
+ object.map {|cluster| cluster}.join("\n")
17
17
  }
18
18
 
19
19
  get '/clusters' do
20
20
  authenticate!
21
21
 
22
- Cabal::API::Cluster.
23
- all.
24
- sort_by(:name, order: 'ALPHA').
25
- map {|cluster| {name: cluster.name}}
22
+ clusters = Cabal::API::ClusterService.new
23
+ clusters.names.sort
26
24
  end
27
25
  end
28
26
  end
@@ -1,5 +1,5 @@
1
1
  module Cabal
2
2
  module Api
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cabal-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dennis Walters
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-24 00:00:00.000000000 Z
11
+ date: 2019-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -109,131 +109,117 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.10'
111
111
  - !ruby/object:Gem::Dependency
112
- name: redis
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: database_cleaner
112
+ name: yard
127
113
  requirement: !ruby/object:Gem::Requirement
128
114
  requirements:
129
- - - ">="
115
+ - - "~>"
130
116
  - !ruby/object:Gem::Version
131
- version: '0'
117
+ version: 0.8.7
132
118
  type: :development
133
119
  prerelease: false
134
120
  version_requirements: !ruby/object:Gem::Requirement
135
121
  requirements:
136
- - - ">="
122
+ - - "~>"
137
123
  - !ruby/object:Gem::Version
138
- version: '0'
124
+ version: 0.8.7
139
125
  - !ruby/object:Gem::Dependency
140
- name: yard
126
+ name: cabal-util
141
127
  requirement: !ruby/object:Gem::Requirement
142
128
  requirements:
143
129
  - - "~>"
144
130
  - !ruby/object:Gem::Version
145
- version: 0.8.7
146
- type: :development
131
+ version: '0.1'
132
+ type: :runtime
147
133
  prerelease: false
148
134
  version_requirements: !ruby/object:Gem::Requirement
149
135
  requirements:
150
136
  - - "~>"
151
137
  - !ruby/object:Gem::Version
152
- version: 0.8.7
138
+ version: '0.1'
153
139
  - !ruby/object:Gem::Dependency
154
- name: cabal-util
140
+ name: grape
155
141
  requirement: !ruby/object:Gem::Requirement
156
142
  requirements:
157
143
  - - "~>"
158
144
  - !ruby/object:Gem::Version
159
- version: '0.1'
145
+ version: '1.2'
160
146
  type: :runtime
161
147
  prerelease: false
162
148
  version_requirements: !ruby/object:Gem::Requirement
163
149
  requirements:
164
150
  - - "~>"
165
151
  - !ruby/object:Gem::Version
166
- version: '0.1'
152
+ version: '1.2'
167
153
  - !ruby/object:Gem::Dependency
168
- name: grape
154
+ name: bcrypt
169
155
  requirement: !ruby/object:Gem::Requirement
170
156
  requirements:
171
157
  - - "~>"
172
158
  - !ruby/object:Gem::Version
173
- version: '0.13'
159
+ version: '3.1'
174
160
  type: :runtime
175
161
  prerelease: false
176
162
  version_requirements: !ruby/object:Gem::Requirement
177
163
  requirements:
178
164
  - - "~>"
179
165
  - !ruby/object:Gem::Version
180
- version: '0.13'
166
+ version: '3.1'
181
167
  - !ruby/object:Gem::Dependency
182
- name: ohm
168
+ name: sshkey
183
169
  requirement: !ruby/object:Gem::Requirement
184
170
  requirements:
185
- - - ">="
171
+ - - "~>"
186
172
  - !ruby/object:Gem::Version
187
- version: '0'
173
+ version: '1.9'
188
174
  type: :runtime
189
175
  prerelease: false
190
176
  version_requirements: !ruby/object:Gem::Requirement
191
177
  requirements:
192
- - - ">="
178
+ - - "~>"
193
179
  - !ruby/object:Gem::Version
194
- version: '0'
180
+ version: '1.9'
195
181
  - !ruby/object:Gem::Dependency
196
- name: ohm-contrib
182
+ name: sekrat
197
183
  requirement: !ruby/object:Gem::Requirement
198
184
  requirements:
199
- - - ">="
185
+ - - "~>"
200
186
  - !ruby/object:Gem::Version
201
- version: '0'
187
+ version: 1.0.0
202
188
  type: :runtime
203
189
  prerelease: false
204
190
  version_requirements: !ruby/object:Gem::Requirement
205
191
  requirements:
206
- - - ">="
192
+ - - "~>"
207
193
  - !ruby/object:Gem::Version
208
- version: '0'
194
+ version: 1.0.0
209
195
  - !ruby/object:Gem::Dependency
210
- name: bcrypt
196
+ name: sekrat-crypter-aes
211
197
  requirement: !ruby/object:Gem::Requirement
212
198
  requirements:
213
- - - ">="
199
+ - - "~>"
214
200
  - !ruby/object:Gem::Version
215
- version: '0'
201
+ version: 1.0.0
216
202
  type: :runtime
217
203
  prerelease: false
218
204
  version_requirements: !ruby/object:Gem::Requirement
219
205
  requirements:
220
- - - ">="
206
+ - - "~>"
221
207
  - !ruby/object:Gem::Version
222
- version: '0'
208
+ version: 1.0.0
223
209
  - !ruby/object:Gem::Dependency
224
- name: sshkey
210
+ name: dry-struct
225
211
  requirement: !ruby/object:Gem::Requirement
226
212
  requirements:
227
- - - ">="
213
+ - - "~>"
228
214
  - !ruby/object:Gem::Version
229
- version: '0'
215
+ version: 0.6.0
230
216
  type: :runtime
231
217
  prerelease: false
232
218
  version_requirements: !ruby/object:Gem::Requirement
233
219
  requirements:
234
- - - ">="
220
+ - - "~>"
235
221
  - !ruby/object:Gem::Version
236
- version: '0'
222
+ version: 0.6.0
237
223
  description:
238
224
  email:
239
225
  - dwalters@engineyard.com
@@ -246,20 +232,25 @@ files:
246
232
  - ".ruby-gemset"
247
233
  - ".ruby-version"
248
234
  - ".travis.yml"
235
+ - Dockerfile
249
236
  - Gemfile
250
237
  - LICENSE.txt
251
238
  - README.md
252
239
  - Rakefile
253
240
  - cabal-api.gemspec
241
+ - docker-compose.yml
254
242
  - lib/cabal/api.rb
255
243
  - lib/cabal/api/base.rb
256
- - lib/cabal/api/cluster.rb
244
+ - lib/cabal/api/cluster_service.rb
257
245
  - lib/cabal/api/common.rb
258
246
  - lib/cabal/api/common/authenticated.rb
259
247
  - lib/cabal/api/common/mistakes.rb
260
248
  - lib/cabal/api/common/private_key.rb
261
249
  - lib/cabal/api/common/public_key.rb
250
+ - lib/cabal/api/common/services.rb
251
+ - lib/cabal/api/types.rb
262
252
  - lib/cabal/api/user.rb
253
+ - lib/cabal/api/user_service.rb
263
254
  - lib/cabal/api/v1/base.rb
264
255
  - lib/cabal/api/v1/public_key.rb
265
256
  - lib/cabal/api/v2/base.rb
@@ -289,10 +280,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
289
280
  - !ruby/object:Gem::Version
290
281
  version: '0'
291
282
  requirements: []
292
- rubyforge_project:
293
- rubygems_version: 2.4.7
283
+ rubygems_version: 3.0.1
294
284
  signing_key:
295
285
  specification_version: 4
296
286
  summary: A Grape API for creating and distributing SSH keys
297
287
  test_files: []
298
- has_rdoc:
@@ -1,39 +0,0 @@
1
- require 'ohm'
2
- require 'ohm/contrib'
3
- require 'sshkey'
4
- require 'cabal/util'
5
-
6
- module Cabal
7
- module API
8
- class Cluster < Ohm::Model
9
- include Ohm::Callbacks
10
-
11
- # The secret key should not be saved plain, but we want to access it
12
- # immediately after creation
13
- attr_accessor :secret_key
14
-
15
- attribute :name
16
- attribute :private_key
17
- attribute :public_key
18
-
19
- # Enable lookups via cluster name
20
- index :name
21
-
22
- # Ensure that cluster name is unique
23
- unique :name
24
-
25
- def before_create
26
- self.name = Cabal::Util.normalize(name)
27
-
28
- sshkey = SSHKey.generate(type: 'RSA', bits: 2048, comment: "#{name}-cabal")
29
- self.private_key = sshkey.private_key
30
- self.public_key = sshkey.ssh_public_key
31
- end
32
-
33
- def self.by_cluster_name(name)
34
- name = Cabal::Util.normalize(name)
35
- find(name: name).first || create(name: name)
36
- end
37
- end
38
- end
39
- end