visor-auth 0.0.1
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.
- data/bin/visor-admin +282 -0
- data/bin/visor-auth +8 -0
- data/lib/auth/backends/base.rb +167 -0
- data/lib/auth/backends/mongo_db.rb +165 -0
- data/lib/auth/backends/mysql_db.rb +186 -0
- data/lib/auth/cli.rb +333 -0
- data/lib/auth/client.rb +149 -0
- data/lib/auth/server.rb +215 -0
- data/lib/auth/version.rb +5 -0
- data/lib/visor-auth.rb +12 -0
- data/spec/lib/server_spec.rb +189 -0
- metadata +203 -0
data/bin/visor-admin
ADDED
@@ -0,0 +1,282 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'uri'
|
5
|
+
require 'visor-common'
|
6
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
7
|
+
require 'auth/version'
|
8
|
+
require 'auth/client'
|
9
|
+
|
10
|
+
# VISoR administration command line interface script.
|
11
|
+
#
|
12
|
+
# Commands:
|
13
|
+
#
|
14
|
+
#list Show all registered users
|
15
|
+
#get Show a specific user
|
16
|
+
#add Register a new user
|
17
|
+
#update Update an user
|
18
|
+
#delete Delete an user
|
19
|
+
#clean Delete all users
|
20
|
+
#help <cmd> Show help message for one of the above commands
|
21
|
+
#
|
22
|
+
# Run <visor -h> to get more usage help.
|
23
|
+
#
|
24
|
+
class VisorAdminCLI
|
25
|
+
include Visor::Common::Exception
|
26
|
+
include Visor::Common::Config
|
27
|
+
|
28
|
+
# VISoR Admin CLI version
|
29
|
+
VERSION = '0.0.1'
|
30
|
+
|
31
|
+
attr_reader :argv, :options, :parser, :command
|
32
|
+
|
33
|
+
# Initialize a new CLI
|
34
|
+
def initialize(argv=ARGV)
|
35
|
+
@argv = argv
|
36
|
+
@options = load_conf_file
|
37
|
+
@parser = parser
|
38
|
+
@command = parse!
|
39
|
+
end
|
40
|
+
|
41
|
+
# OptionParser parser
|
42
|
+
def parser
|
43
|
+
OptionParser.new do |opts|
|
44
|
+
opts.banner = "Usage: visor-admin <command> [options]"
|
45
|
+
|
46
|
+
opts.separator ""
|
47
|
+
opts.separator "Commands:"
|
48
|
+
opts.separator " list Show all registered users"
|
49
|
+
opts.separator " get Show a specific user"
|
50
|
+
opts.separator " add Register a new user"
|
51
|
+
opts.separator " update Update an user"
|
52
|
+
opts.separator " delete Delete an user"
|
53
|
+
opts.separator " clean Delete all users"
|
54
|
+
opts.separator " help <cmd> Show help message for one of the above commands"
|
55
|
+
|
56
|
+
opts.separator ""
|
57
|
+
opts.separator "Options:"
|
58
|
+
opts.on("-a", "--access KEY", "The user access key (username)") { |key| options[:access_key] = key }
|
59
|
+
opts.on("-e", "--email ADDRESS", "The user email address") { |addr| options[:email] = addr }
|
60
|
+
opts.on("-q", "--query QUERY", "HTTP query like string to filter results") do |query|
|
61
|
+
(options[:query] = URI.decode_www_form(query)) rescue abort "The provided query string is not valid."
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.separator ""
|
65
|
+
opts.separator "Common options:"
|
66
|
+
opts.on_tail("-D", "--dry-run", "Don't persist results, just print what would it do") { options[:dry] = true }
|
67
|
+
opts.on_tail('-v', '--verbose', "Enable verbose") { options[:verbose] = true }
|
68
|
+
opts.on_tail("-h", "--help", "Show this help message") { puts opts; exit 0 }
|
69
|
+
opts.on_tail('-V', '--version', "Show version") { puts "VISoR Admin CLI v#{VERSION}"; exit 0 }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Parse argv arguments
|
74
|
+
def parse!
|
75
|
+
parser.parse! ARGV
|
76
|
+
ARGV.shift
|
77
|
+
end
|
78
|
+
|
79
|
+
# Parse the current shell arguments and run the command
|
80
|
+
def run!
|
81
|
+
abort parser.to_s if command.nil?
|
82
|
+
start = Time.now
|
83
|
+
case command
|
84
|
+
when 'list' then
|
85
|
+
list
|
86
|
+
when 'get' then
|
87
|
+
get
|
88
|
+
when 'add' then
|
89
|
+
add
|
90
|
+
when 'update' then
|
91
|
+
update
|
92
|
+
when 'delete' then
|
93
|
+
delete
|
94
|
+
when 'help' then
|
95
|
+
help
|
96
|
+
else
|
97
|
+
abort "Unknown command '#{command}'"
|
98
|
+
end
|
99
|
+
finish = Time.now
|
100
|
+
printf("Done in %-0.4f seconds", finish - start) if verbose?
|
101
|
+
exit 0
|
102
|
+
end
|
103
|
+
|
104
|
+
# Show all registered users
|
105
|
+
def list
|
106
|
+
users = client.get_users(options[:query])
|
107
|
+
puts "Found #{users.size} users..."
|
108
|
+
print_users(users)
|
109
|
+
rescue NotFound => e
|
110
|
+
puts e.message
|
111
|
+
rescue => e
|
112
|
+
abort "Failure while executing 'list':\n#{e.message}"
|
113
|
+
end
|
114
|
+
|
115
|
+
# Retrieve an user
|
116
|
+
def get
|
117
|
+
access_key = argv.shift
|
118
|
+
abort "No user access key provided as first argument, please provide it." unless access_key
|
119
|
+
user = client.get_user(access_key)
|
120
|
+
print_users(user)
|
121
|
+
rescue NotFound => e
|
122
|
+
puts e.message
|
123
|
+
rescue => e
|
124
|
+
abort "Failure while executing 'get':\n#{e.message}"
|
125
|
+
end
|
126
|
+
|
127
|
+
# Add a new user
|
128
|
+
def add
|
129
|
+
begin
|
130
|
+
info = parse_info_from_args
|
131
|
+
user = client.post_user(info)
|
132
|
+
puts "Successfully added new user with access key '#{user[:access_key]}'."
|
133
|
+
print_users(user)
|
134
|
+
rescue NotFound => e
|
135
|
+
puts e.message
|
136
|
+
rescue => e
|
137
|
+
abort "Failure while executing 'add':\n#{e.message}"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Update an user
|
142
|
+
def update
|
143
|
+
access_key = argv.shift
|
144
|
+
abort "No user access key provided as first argument, please provide it." unless access_key
|
145
|
+
begin
|
146
|
+
info = parse_info_from_args
|
147
|
+
user = client.put_user(access_key, info)
|
148
|
+
puts "Successfully updated the user #{access_key}."
|
149
|
+
print_users(user) if verbose?
|
150
|
+
rescue NotFound => e
|
151
|
+
puts e.message
|
152
|
+
rescue => e
|
153
|
+
abort "Failure while executing 'update':\n#{e.message}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Delete an user
|
158
|
+
def delete
|
159
|
+
begin
|
160
|
+
argv.each do |access_key|
|
161
|
+
abort "No user access key provided as first argument, please provide it." unless access_key
|
162
|
+
user = client.delete_user(access_key)
|
163
|
+
puts "Successfully deleted user #{access_key}."
|
164
|
+
print_users(user) if verbose?
|
165
|
+
end
|
166
|
+
end
|
167
|
+
rescue NotFound => e
|
168
|
+
puts e.message
|
169
|
+
rescue => e
|
170
|
+
abort "Failure while executing 'delete':\n#{e.message}"
|
171
|
+
end
|
172
|
+
|
173
|
+
# Show help message for one of the above commands
|
174
|
+
def help
|
175
|
+
cmd = argv[0]
|
176
|
+
abort "Please provide a command name as argument (example: visor-admin help list)." unless cmd
|
177
|
+
|
178
|
+
case cmd.to_sym
|
179
|
+
when :list
|
180
|
+
puts %q[Usage: visor-admin list [options]
|
181
|
+
|
182
|
+
Returns a list of all registered users.
|
183
|
+
|
184
|
+
You can filter results based on a query using the --query (-q) option.
|
185
|
+
|
186
|
+
Examples:
|
187
|
+
$ visor-admin list
|
188
|
+
$ visor-admin list --query email=foo@bar.com]
|
189
|
+
when :get
|
190
|
+
puts %q[Usage: visor-admin get <ACCESS KEY> [options]
|
191
|
+
|
192
|
+
Returns the account information of the user with the given access key.
|
193
|
+
|
194
|
+
Examples:
|
195
|
+
$ visor get foo]
|
196
|
+
when :add
|
197
|
+
puts %q[Usage: visor-admin add <ATTRIBUTES> [options]
|
198
|
+
|
199
|
+
Add a new user, providing its attributes.
|
200
|
+
|
201
|
+
The following attributes can be specified as key/value pairs:
|
202
|
+
|
203
|
+
access_key: The wanted user access key (username)
|
204
|
+
email: The user email address
|
205
|
+
|
206
|
+
Examples:
|
207
|
+
$ visor-admin add access_key=foo email=foo@bar.com]
|
208
|
+
when :update
|
209
|
+
puts %q[Usage: visor-admin update <ACCESS KEY> [options]
|
210
|
+
|
211
|
+
Updates the account information of the user with the given access key.
|
212
|
+
|
213
|
+
The following attributes can be specified as key/value pairs:
|
214
|
+
|
215
|
+
access_key: The wanted user access key (username)
|
216
|
+
email: The user email address
|
217
|
+
|
218
|
+
Examples:
|
219
|
+
$ visor update foo email=bar@foo.com]
|
220
|
+
when :delete
|
221
|
+
puts %q[Usage: visor-admin delete <ACCESS KEY> [options]
|
222
|
+
|
223
|
+
Deletes the account of the user with the given access key.
|
224
|
+
|
225
|
+
Examples:
|
226
|
+
$ visor delete foo]
|
227
|
+
else
|
228
|
+
abort "Unknown command '#{cmd}'"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
private
|
233
|
+
|
234
|
+
# Pretty print users
|
235
|
+
def print_users(user)
|
236
|
+
str = "%-37s %-18s %-41s %-27s %-24s %-24s\n"
|
237
|
+
printf(str, 'ID', 'ACCESS KEY', 'SECRET KEY', 'EMAIL', 'CREATED AT', 'UPDATED AT')
|
238
|
+
puts "#{'-'*36+" "+'-'*17+" "+'-'*40+" "+'-'*26+" "+'-'*23+" "+'-'*23}"
|
239
|
+
|
240
|
+
if user.is_a?(Array)
|
241
|
+
user.each { |u| printf(str, u[:_id], u[:access_key], u[:secret_key], u[:email] || '-', u[:created_at] || '-', u[:updated_at] || '-') }
|
242
|
+
else
|
243
|
+
printf(str, user[:_id], user[:access_key], user[:secret_key], user[:email] || '-', user[:created_at] || '-', user[:updated_at] || '-')
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
# Load configuration file options
|
248
|
+
def load_conf_file
|
249
|
+
config = Visor::Common::Config.load_config(:visor_auth)
|
250
|
+
{host: config[:bind_host], port: config[:bind_port]}
|
251
|
+
rescue => e
|
252
|
+
raise "There was an error loading the configuration file: #{e.message}"
|
253
|
+
end
|
254
|
+
|
255
|
+
# Get a new VISoR Auth Client instance
|
256
|
+
def client
|
257
|
+
Visor::Auth::Client.new(options)
|
258
|
+
end
|
259
|
+
|
260
|
+
# Find if verbose mode is active
|
261
|
+
def verbose?
|
262
|
+
options[:verbose]
|
263
|
+
end
|
264
|
+
|
265
|
+
# Parse key/value pair arguments to a valid hash
|
266
|
+
def parse_info_from_args
|
267
|
+
info = {}
|
268
|
+
raise "You should provide at least one key=value pair." if argv.empty?
|
269
|
+
argv.each do |arg|
|
270
|
+
k, v = arg.split('=')
|
271
|
+
raise "Arguments should be in the form of key=value pairs." unless k && v
|
272
|
+
info[k.downcase.sub('-', '_')] = v
|
273
|
+
end
|
274
|
+
info
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# Execute if file is called
|
279
|
+
#if __FILE__ == $0
|
280
|
+
VisorAdminCLI.new.run!
|
281
|
+
#end
|
282
|
+
|
data/bin/visor-auth
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Visor
|
4
|
+
module Auth
|
5
|
+
module Backends
|
6
|
+
|
7
|
+
# This is the Base super class for all Backends. Each new backend inherits from Base,
|
8
|
+
# which contains the model and all validations for the users metadata.
|
9
|
+
#
|
10
|
+
# Implementing a new backend is as simple as create a new backend class which inherits
|
11
|
+
# from Base and them implement the specific methods for querying the underlying database.
|
12
|
+
#
|
13
|
+
class Base
|
14
|
+
|
15
|
+
# Keys validation
|
16
|
+
#
|
17
|
+
# Mandatory attributes
|
18
|
+
MANDATORY = [:access_key, :email]
|
19
|
+
# Read-only attributes
|
20
|
+
READONLY = [:_id, :secret_key, :created_at, :updated_at]
|
21
|
+
# All attributes
|
22
|
+
ALL = MANDATORY + READONLY
|
23
|
+
|
24
|
+
attr_reader :db, :host, :port, :user, :password, :conn
|
25
|
+
|
26
|
+
# Initializes a Backend instance.
|
27
|
+
#
|
28
|
+
# @option [Hash] opts Any of the available options can be passed.
|
29
|
+
#
|
30
|
+
# @option opts [String] :host The host address.
|
31
|
+
# @option opts [Integer] :port The port to be used.
|
32
|
+
# @option opts [String] :db The wanted database.
|
33
|
+
# @option opts [String] :user The username to be authenticate db access.
|
34
|
+
# @option opts [String] :password The password to be authenticate db access.
|
35
|
+
# @option opts [Object] :conn The connection pool to access database.
|
36
|
+
#
|
37
|
+
def initialize(opts)
|
38
|
+
@host = opts[:host]
|
39
|
+
@port = opts[:port]
|
40
|
+
@db = opts[:db]
|
41
|
+
@user = opts[:user]
|
42
|
+
@password = opts[:password]
|
43
|
+
@conn = opts[:conn]
|
44
|
+
end
|
45
|
+
|
46
|
+
# Validates the user information for a post operation, based on possible keys and values.
|
47
|
+
#
|
48
|
+
# @param [Hash] info The user information.
|
49
|
+
#
|
50
|
+
# @raise[ArgumentError] If some of the information fields do not respect the
|
51
|
+
# possible values, contains any read-only or misses any mandatory field.
|
52
|
+
#
|
53
|
+
def validate_data_post(info)
|
54
|
+
info.assert_exclusion_keys(READONLY)
|
55
|
+
info.assert_inclusion_keys(MANDATORY)
|
56
|
+
validate_email(info[:email])
|
57
|
+
end
|
58
|
+
|
59
|
+
# Validates the user information for a put operation, based on possible keys and values.
|
60
|
+
#
|
61
|
+
# @param [Hash] info The user information.
|
62
|
+
#
|
63
|
+
# @raise[ArgumentError] If some of the metadata fields do not respect the
|
64
|
+
# possible values, contains any read-only or misses any mandatory field.
|
65
|
+
#
|
66
|
+
def validate_data_put(info)
|
67
|
+
info.assert_exclusion_keys(READONLY)
|
68
|
+
validate_email(info[:email]) if info[:email]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set protected fields value from a post operation.
|
72
|
+
# Being them the _id and created_at.
|
73
|
+
#
|
74
|
+
# @param [Hash] info The user information.
|
75
|
+
#
|
76
|
+
# @option [Hash] opts Any of the available options can be passed.
|
77
|
+
#
|
78
|
+
# @return [Hash] The updated user information.
|
79
|
+
#
|
80
|
+
def set_protected_post(info)
|
81
|
+
info.merge!(_id: SecureRandom.uuid, secret_key: SecureRandom.base64(30), created_at: Time.now)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Set protected field value from a get operation.
|
85
|
+
# Being it the updated_at.
|
86
|
+
#
|
87
|
+
# @param [Hash] info The user information update.
|
88
|
+
#
|
89
|
+
# @return [Hash] The updated user information.
|
90
|
+
#
|
91
|
+
def set_protected_put(info)
|
92
|
+
info.merge!(updated_at: Time.now)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Generates a compatible SQL WHERE string from a hash.
|
96
|
+
#
|
97
|
+
# @param [Hash] h The input hash.
|
98
|
+
#
|
99
|
+
# @return [String] A string as "k='v' AND k1='v1'",
|
100
|
+
# only Strings Times or Hashes values are surrounded with '<value>'.
|
101
|
+
#
|
102
|
+
def to_sql_where(h)
|
103
|
+
h.map { |k, v| string_time_or_hash?(v) ? "#{k}='#{v}'" : "#{k}=#{v}" }.join(' AND ')
|
104
|
+
end
|
105
|
+
|
106
|
+
# Generates a compatible SQL UPDATE string from a hash.
|
107
|
+
#
|
108
|
+
# @param [Hash] h The input hash.
|
109
|
+
#
|
110
|
+
# @return [String] A string as "k='v', k1='v1'",
|
111
|
+
# only Strings Times or Hashes values are surrounded with '<value>'.
|
112
|
+
#
|
113
|
+
def to_sql_update(h)
|
114
|
+
h.map { |k, v| string_time_or_hash?(v) ? "#{k}='#{v}'" : "#{k}=#{v}" }.join(', ')
|
115
|
+
end
|
116
|
+
|
117
|
+
# Generates a compatible SQL INSERT string from a hash.
|
118
|
+
#
|
119
|
+
# @param [Hash] h The input hash.
|
120
|
+
#
|
121
|
+
# @return [String] A string as "(k, k1) VALUES ('v', 'v1')",
|
122
|
+
# only Strings Times or Hashes values are surrounded with '<value>'.
|
123
|
+
#
|
124
|
+
def to_sql_insert(h)
|
125
|
+
surround = h.values.map { |v| string_time_or_hash?(v) ? "'#{v}'" : v }
|
126
|
+
%W{(#{h.keys.join(', ')}) (#{surround.join(', ')})}
|
127
|
+
end
|
128
|
+
|
129
|
+
# Validates that incoming query filters fields are valid.
|
130
|
+
#
|
131
|
+
# @param [Hash] filters The image metadata filters coming from a GET request.
|
132
|
+
#
|
133
|
+
# @raise[ArgumentError] If some of the query filter fields do not respect the
|
134
|
+
# possible values.
|
135
|
+
#
|
136
|
+
def validate_query_filters(filters)
|
137
|
+
filters.symbolize_keys!
|
138
|
+
filters.assert_valid_keys(ALL)
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# Verifies if a given object is a String, a Time or a Hash.
|
144
|
+
#
|
145
|
+
# @param [Object] v The input value.
|
146
|
+
#
|
147
|
+
# @return [true, false] If the provided value is or not a String, a Time or a Hash.
|
148
|
+
#
|
149
|
+
def string_time_or_hash?(v)
|
150
|
+
v.is_a?(String) or v.is_a?(Time) or v.is_a?(Hash)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Verifies if a given email string is a valid email.
|
154
|
+
#
|
155
|
+
# @param [String] s The input value.
|
156
|
+
#
|
157
|
+
# @raise [ArgumentError] If the email address is invalid.
|
158
|
+
#
|
159
|
+
def validate_email(s)
|
160
|
+
valid = s.match(/([^@\s*]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})/i)
|
161
|
+
raise ArgumentError, "The email address seems to be invalid." unless valid
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
module Visor
|
5
|
+
module Auth
|
6
|
+
module Backends
|
7
|
+
|
8
|
+
# The MongoDB Backend for the VISoR Auth.
|
9
|
+
#
|
10
|
+
class MongoDB < Base
|
11
|
+
|
12
|
+
include Visor::Common::Exception
|
13
|
+
|
14
|
+
# Connection constants
|
15
|
+
#
|
16
|
+
# Default MongoDB database
|
17
|
+
DEFAULT_DB = 'visor'
|
18
|
+
# Default MongoDB host address
|
19
|
+
DEFAULT_HOST = '127.0.0.1'
|
20
|
+
# Default MongoDB host port
|
21
|
+
DEFAULT_PORT = 27017
|
22
|
+
# Default MongoDB user
|
23
|
+
DEFAULT_USER = nil
|
24
|
+
# Default MongoDB password
|
25
|
+
DEFAULT_PASSWORD = nil
|
26
|
+
|
27
|
+
# Initializes a MongoDB Backend instance.
|
28
|
+
#
|
29
|
+
# @option [Hash] opts Any of the available options can be passed.
|
30
|
+
#
|
31
|
+
# @option opts [String] :uri The connection uri, if provided, no other option needs to be setted.
|
32
|
+
# @option opts [String] :db (DEFAULT_DB) The wanted database.
|
33
|
+
# @option opts [String] :host (DEFAULT_HOST) The host address.
|
34
|
+
# @option opts [Integer] :port (DEFAULT_PORT) The port to be used.
|
35
|
+
# @option opts [String] :user (DEFAULT_USER) The user to be used.
|
36
|
+
# @option opts [String] :password (DEFAULT_PASSWORD) The password to be used.
|
37
|
+
# @option opts [Object] :conn The connection pool to access database.
|
38
|
+
#
|
39
|
+
def self.connect(opts = {})
|
40
|
+
opts[:uri] ||= ''
|
41
|
+
uri = URI.parse(opts[:uri])
|
42
|
+
opts[:db] = uri.path ? uri.path.gsub('/', '') : DEFAULT_DB
|
43
|
+
opts[:host] = uri.host || DEFAULT_HOST
|
44
|
+
opts[:port] = uri.port || DEFAULT_PORT
|
45
|
+
opts[:user] = uri.user || DEFAULT_USER
|
46
|
+
opts[:password] = uri.password || DEFAULT_PASSWORD
|
47
|
+
|
48
|
+
self.new opts
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize(opts)
|
52
|
+
super opts
|
53
|
+
@conn = connection
|
54
|
+
end
|
55
|
+
|
56
|
+
# Establishes and returns a MongoDB database connection.
|
57
|
+
#
|
58
|
+
# @return [Mongo::Collection] A MongoDB collection object.
|
59
|
+
#
|
60
|
+
def connection
|
61
|
+
db = Mongo::Connection.new(@host, @port, :pool_size => 10, :pool_timeout => 5).db(@db)
|
62
|
+
db.authenticate(@user, @password) unless @user.empty? && @password.empty?
|
63
|
+
db.collection('users')
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns an array with the registered users.
|
67
|
+
#
|
68
|
+
# @option [Hash] filters Users attributes for filtering the returned results.
|
69
|
+
# Besides common attributes filters, the following options can be passed to.
|
70
|
+
#
|
71
|
+
# @return [Array] The users information.
|
72
|
+
#
|
73
|
+
# @raise [NotFound] If there are no registered users.
|
74
|
+
#
|
75
|
+
def get_users(filters = {})
|
76
|
+
validate_query_filters filters unless filters.empty?
|
77
|
+
users = @conn.find(filters).to_a
|
78
|
+
raise NotFound, "No users found." if users.empty? && filters.empty?
|
79
|
+
raise NotFound, "No users found with given parameters." if users.empty?
|
80
|
+
users
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns an user information.
|
84
|
+
#
|
85
|
+
# @param [String] access_key The user access_key.
|
86
|
+
#
|
87
|
+
# @return [BSON::OrderedHash] The requested user information.
|
88
|
+
#
|
89
|
+
# @raise [NotFound] If user was not found.
|
90
|
+
#
|
91
|
+
def get_user(access_key)
|
92
|
+
user = @conn.find_one(access_key: access_key)
|
93
|
+
raise NotFound, "No user found with Access Key '#{access_key}'." unless user
|
94
|
+
user
|
95
|
+
end
|
96
|
+
|
97
|
+
# Delete a registered user.
|
98
|
+
#
|
99
|
+
# @param [String] access_key The user access_key.
|
100
|
+
#
|
101
|
+
# @return [BSON::OrderedHash] The deleted image metadata.
|
102
|
+
#
|
103
|
+
# @raise [NotFound] If user was not found.
|
104
|
+
#
|
105
|
+
def delete_user(access_key)
|
106
|
+
user = @conn.find_one(access_key: access_key)
|
107
|
+
raise NotFound, "No user found with Access Key '#{access_key}'." unless user
|
108
|
+
@conn.remove(access_key: access_key)
|
109
|
+
user
|
110
|
+
end
|
111
|
+
|
112
|
+
# Delete all registered users.
|
113
|
+
#
|
114
|
+
def delete_all!
|
115
|
+
@conn.remove
|
116
|
+
end
|
117
|
+
|
118
|
+
# Create a new user record for the given information.
|
119
|
+
#
|
120
|
+
# @param [Hash] user The user information.
|
121
|
+
#
|
122
|
+
# @return [BSON::OrderedHash] The already added user information.
|
123
|
+
#
|
124
|
+
# @raise [Invalid] If user information validation fails.
|
125
|
+
# @raise [ConflictError] If an access_key was already taken.
|
126
|
+
#
|
127
|
+
def post_user(user)
|
128
|
+
validate_data_post user
|
129
|
+
exists = @conn.find_one(access_key: user[:access_key])
|
130
|
+
raise ConflictError, "The Access Key '#{user[:access_key]}' was already taken." if exists
|
131
|
+
set_protected_post user
|
132
|
+
@conn.insert(user)
|
133
|
+
self.get_user(user[:access_key])
|
134
|
+
end
|
135
|
+
|
136
|
+
# Update an user information.
|
137
|
+
#
|
138
|
+
# @param [String] access_key The user access_key.
|
139
|
+
# @param [Hash] update The user information update.
|
140
|
+
#
|
141
|
+
# @return [BSON::OrderedHash] The updated user information.
|
142
|
+
#
|
143
|
+
# @raise [Invalid] If user information validation fails.
|
144
|
+
# @raise [ConflictError] If an access_key was already taken.
|
145
|
+
# @raise [NotFound] If user was not found.
|
146
|
+
#
|
147
|
+
def put_user(access_key, update)
|
148
|
+
validate_data_put update
|
149
|
+
user = @conn.find_one(access_key: access_key)
|
150
|
+
raise NotFound, "No user found with Access Key '#{access_key}'." unless user
|
151
|
+
if update[:access_key]
|
152
|
+
exists = @conn.find_one(access_key: update[:access_key])
|
153
|
+
raise ConflictError, "The Access Key '#{update[:access_key]}' was already taken." if exists
|
154
|
+
end
|
155
|
+
set_protected_put update
|
156
|
+
@conn.update({access_key: access_key}, :$set => update)
|
157
|
+
self.get_user(update[:access_key] || access_key)
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|