cabal-api 0.0.1 → 0.0.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 +4 -4
- data/cabal-api.gemspec +6 -1
- data/lib/cabal/api/base.rb +2 -0
- data/lib/cabal/api/cluster.rb +39 -0
- data/lib/cabal/api/common/authenticated.rb +30 -0
- data/lib/cabal/api/common/mistakes.rb +21 -0
- data/lib/cabal/api/common/public_key.rb +26 -0
- data/lib/cabal/api/common.rb +1 -0
- data/lib/cabal/api/user.rb +49 -0
- data/lib/cabal/api/v1/base.rb +0 -1
- data/lib/cabal/api/v1/public_key.rb +2 -12
- data/lib/cabal/api/v2/base.rb +16 -0
- data/lib/cabal/api/v2/private_key.rb +46 -0
- data/lib/cabal/api/v2/public_key.rb +13 -0
- data/lib/cabal/api/version.rb +1 -1
- data/lib/cabal/api.rb +6 -2
- metadata +89 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 633175e3c38cc1c65baddaedcd27f2759e89a1af
|
4
|
+
data.tar.gz: b547ecf19c5443809c21be14cc22fe1466055962
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5d78bb2f96f4d25a08d85edbb72cb376ddfb008d838364d61c4ed2be0a0c9859876072ddfc06f58888df3b9cacb355af26a2cd9bd7e53788123ecbc79d6ec4c
|
7
|
+
data.tar.gz: a3c43b4d082fb850033607e999467e214cdc557641145ac41b356606bbae08843c5e5cec6939dca697ab9c02b4af63b9d2a502d538482cbe1aeaefe2268b60f0
|
data/cabal-api.gemspec
CHANGED
@@ -24,8 +24,13 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rack-test", '~> 0.6'
|
25
25
|
spec.add_development_dependency "rspec", '~> 3.3'
|
26
26
|
spec.add_development_dependency "factis", '~> 1.0'
|
27
|
-
spec.add_development_dependency "fakeredis", '~> 0.5'
|
28
27
|
spec.add_development_dependency "simplecov", '~> 0.10'
|
28
|
+
spec.add_development_dependency "redis"
|
29
|
+
spec.add_development_dependency "database_cleaner"
|
29
30
|
spec.add_runtime_dependency "cabal", '~> 0.2'
|
30
31
|
spec.add_runtime_dependency "grape", '~> 0.13'
|
32
|
+
spec.add_runtime_dependency "ohm"
|
33
|
+
spec.add_runtime_dependency "ohm-contrib"
|
34
|
+
spec.add_runtime_dependency "bcrypt"
|
35
|
+
spec.add_runtime_dependency "sshkey"
|
31
36
|
end
|
data/lib/cabal/api/base.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
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
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'cabal/api/user'
|
2
|
+
|
3
|
+
module Cabal
|
4
|
+
module API
|
5
|
+
module Common
|
6
|
+
module Authenticated
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
helpers do
|
10
|
+
def current_user
|
11
|
+
authorization = headers['Authorization'].to_s
|
12
|
+
access_key, signature = authorization.split(':')
|
13
|
+
user = Cabal::API::User.find(access_key: access_key).first
|
14
|
+
if user && user.authenticated_with?(signature)
|
15
|
+
user
|
16
|
+
else
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def authenticate!
|
22
|
+
error!({message: 'Unauthorized.'}, 401) unless current_user
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Cabal
|
2
|
+
module API
|
3
|
+
module Common
|
4
|
+
module Mistakes
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
error_formatter :txt, ->(message, backtrace, options, env) {
|
8
|
+
message[:message]
|
9
|
+
}
|
10
|
+
|
11
|
+
helpers do
|
12
|
+
def messagify(message)
|
13
|
+
{message: message}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'cabal/util'
|
2
|
+
require 'cabal/api/cluster'
|
3
|
+
|
4
|
+
module Cabal
|
5
|
+
module API
|
6
|
+
module Common
|
7
|
+
module PublicKey
|
8
|
+
def self.included(base)
|
9
|
+
base.class_eval do
|
10
|
+
formatter :txt, ->(object, env) {
|
11
|
+
object[:public_ssh_key]
|
12
|
+
}
|
13
|
+
|
14
|
+
get '/key/:name' do
|
15
|
+
cluster = Cabal::API::Cluster.by_cluster_name(params[:name])
|
16
|
+
{
|
17
|
+
name: cluster.name,
|
18
|
+
public_ssh_key: cluster.public_key
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'cabal/api/common/public_key'
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'ohm'
|
2
|
+
require 'ohm/contrib'
|
3
|
+
require 'bcrypt'
|
4
|
+
require 'securerandom'
|
5
|
+
|
6
|
+
module Cabal
|
7
|
+
module API
|
8
|
+
class User < 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 :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
|
30
|
+
end
|
31
|
+
|
32
|
+
def authenticated_with?(secret_key)
|
33
|
+
return false unless crypted_secret_key
|
34
|
+
|
35
|
+
BCrypt::Password.new(crypted_secret_key) == secret_key
|
36
|
+
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
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/cabal/api/v1/base.rb
CHANGED
@@ -1,22 +1,12 @@
|
|
1
1
|
require 'grape'
|
2
|
-
require 'cabal/cluster'
|
3
2
|
require 'cabal/util'
|
3
|
+
require 'cabal/api/common'
|
4
4
|
|
5
5
|
module Cabal
|
6
6
|
module API
|
7
7
|
module V1
|
8
8
|
class PublicKey < Grape::API
|
9
|
-
|
10
|
-
object[:public_ssh_key]
|
11
|
-
}
|
12
|
-
|
13
|
-
get '/key/:name' do
|
14
|
-
name = Cabal::Util.normalize(params[:name])
|
15
|
-
{
|
16
|
-
name: name,
|
17
|
-
public_ssh_key: Cabal::Cluster.new(name).public_ssh_key
|
18
|
-
}
|
19
|
-
end
|
9
|
+
include Cabal::API::Common::PublicKey
|
20
10
|
end
|
21
11
|
end
|
22
12
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'grape'
|
2
|
+
require 'cabal/api/v2/public_key'
|
3
|
+
require 'cabal/api/v2/private_key'
|
4
|
+
|
5
|
+
module Cabal
|
6
|
+
module API
|
7
|
+
module V2
|
8
|
+
class Base < Grape::API
|
9
|
+
version 'v2', using: :path
|
10
|
+
|
11
|
+
mount Cabal::API::V2::PublicKey
|
12
|
+
mount Cabal::API::V2::PrivateKey
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'grape'
|
2
|
+
require 'cabal/util'
|
3
|
+
require 'cabal/api/cluster'
|
4
|
+
require 'cabal/api/user'
|
5
|
+
require 'cabal/api/common/authenticated'
|
6
|
+
require 'cabal/api/common/mistakes'
|
7
|
+
|
8
|
+
module Cabal
|
9
|
+
module API
|
10
|
+
module V2
|
11
|
+
class PrivateKey < Grape::API
|
12
|
+
include Cabal::API::Common::Authenticated
|
13
|
+
include Cabal::API::Common::Mistakes
|
14
|
+
|
15
|
+
formatter :txt, ->(object, env) {
|
16
|
+
object[:private_ssh_key]
|
17
|
+
}
|
18
|
+
|
19
|
+
helpers do
|
20
|
+
def error_if_not_found!(cluster, name)
|
21
|
+
unless cluster
|
22
|
+
error!(
|
23
|
+
messagify("The cluster '#{name}' could not be found."),
|
24
|
+
404
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
get '/private-key/:name' do
|
31
|
+
authenticate!
|
32
|
+
|
33
|
+
cluster_name = Cabal::Util.normalize(params[:name])
|
34
|
+
cluster = Cabal::API::Cluster.find(name: cluster_name).first
|
35
|
+
|
36
|
+
error_if_not_found!(cluster, cluster_name)
|
37
|
+
|
38
|
+
{
|
39
|
+
name: cluster.name,
|
40
|
+
private_ssh_key: cluster.private_key
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/cabal/api/version.rb
CHANGED
data/lib/cabal/api.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'ohm'
|
2
|
+
require 'cabal/api/version'
|
3
|
+
require 'cabal/api/base'
|
4
|
+
require 'cabal/api/cluster'
|
5
|
+
require 'cabal/api/user'
|
3
6
|
|
4
7
|
module Cabal
|
5
8
|
module Api
|
9
|
+
Ohm.redis = Redic.new(ENV['REDIS_URL'] || 'redis://localhost:6379')
|
6
10
|
end
|
7
11
|
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.0.
|
4
|
+
version: 0.0.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: 2015-10-
|
11
|
+
date: 2015-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,33 +95,47 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: simplecov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
103
|
+
version: '0.10'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0.
|
110
|
+
version: '0.10'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: redis
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - "
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0
|
117
|
+
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - "
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: database_cleaner
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: cabal
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +164,62 @@ dependencies:
|
|
150
164
|
- - "~>"
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0.13'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: ohm
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: ohm-contrib
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: bcrypt
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: sshkey
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :runtime
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
153
223
|
description:
|
154
224
|
email:
|
155
225
|
- dwalters@engineyard.com
|
@@ -172,8 +242,17 @@ files:
|
|
172
242
|
- config/cucumber.yml
|
173
243
|
- lib/cabal/api.rb
|
174
244
|
- lib/cabal/api/base.rb
|
245
|
+
- lib/cabal/api/cluster.rb
|
246
|
+
- lib/cabal/api/common.rb
|
247
|
+
- lib/cabal/api/common/authenticated.rb
|
248
|
+
- lib/cabal/api/common/mistakes.rb
|
249
|
+
- lib/cabal/api/common/public_key.rb
|
250
|
+
- lib/cabal/api/user.rb
|
175
251
|
- lib/cabal/api/v1/base.rb
|
176
252
|
- lib/cabal/api/v1/public_key.rb
|
253
|
+
- lib/cabal/api/v2/base.rb
|
254
|
+
- lib/cabal/api/v2/private_key.rb
|
255
|
+
- lib/cabal/api/v2/public_key.rb
|
177
256
|
- lib/cabal/api/version.rb
|
178
257
|
homepage: http://github.com/ess/cabal-api
|
179
258
|
licenses:
|