cabal-api 0.2.2 → 0.2.3

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
- 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