zas-service 0.0.2 → 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.
- data/lib/zas/authenticators/filtered_authenticator.rb +8 -5
- data/lib/zas/authenticators/sequel_password_authenticator.rb +10 -4
- data/lib/zas/crypto_providers/sha512.rb +11 -6
- data/lib/zas/filters/http_basic_auth.rb +2 -2
- data/lib/zas/filters/standard_auth.rb +7 -1
- data/lib/zas/service.rb +11 -6
- metadata +1 -1
@@ -1,6 +1,6 @@
|
|
1
1
|
module Zas
|
2
2
|
module Authenticators
|
3
|
-
# An authenticator that filters the credentials through 1 or more filters that can transform
|
3
|
+
# Public: An authenticator that filters the credentials through 1 or more filters that can transform
|
4
4
|
# the credentials before passing them to another authenticator.
|
5
5
|
#
|
6
6
|
# Example:
|
@@ -10,7 +10,7 @@ module Zas
|
|
10
10
|
class FilteredAuthenticator
|
11
11
|
attr_accessor :logger
|
12
12
|
|
13
|
-
# Initialize the filtered authenticator with the given delegate
|
13
|
+
# Public: Initialize the filtered authenticator with the given delegate
|
14
14
|
# and filters. Filters will be applied when the authentication
|
15
15
|
# occurs.
|
16
16
|
#
|
@@ -21,13 +21,16 @@ module Zas
|
|
21
21
|
self.filters = [filters].compact.flatten
|
22
22
|
end
|
23
23
|
|
24
|
-
# Authenticate the given credentials.
|
24
|
+
# Public: Authenticate the given credentials.
|
25
25
|
#
|
26
26
|
# credentials - The credentials
|
27
|
+
#
|
28
|
+
# Returns true if the credentials are authenticated
|
27
29
|
def authenticate(credentials)
|
28
|
-
logger.info "Applying filters to credentials: #{filters.join(', ')}"
|
30
|
+
logger.info "Applying filters to credentials: #{filters.join(', ')}" if logger
|
29
31
|
credentials = filters.reduce(credentials) { |credentials, filter| filter.authenticate(credentials) }
|
30
|
-
logger.info "Delegating to #{delegate.class.name}"
|
32
|
+
logger.info "Delegating to #{delegate.class.name}" if logger
|
33
|
+
delegate.logger ||= logger
|
31
34
|
delegate.authenticate(*credentials)
|
32
35
|
end
|
33
36
|
|
@@ -30,9 +30,10 @@ module Zas
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
# Public: a logger.
|
33
34
|
attr_accessor :logger
|
34
35
|
|
35
|
-
# Initialize the autenticator with the given sequel DB. Optionally pass in additional
|
36
|
+
# Public: Initialize the autenticator with the given sequel DB. Optionally pass in additional
|
36
37
|
# configuration for the authenticator.
|
37
38
|
#
|
38
39
|
# sequel_db - The Sequel Datbase instance
|
@@ -45,11 +46,16 @@ module Zas
|
|
45
46
|
self.salt_field = config.salt_field.to_sym
|
46
47
|
end
|
47
48
|
|
48
|
-
# Authenticate the given username/password pair
|
49
|
+
# Public: Authenticate the given username/password pair
|
50
|
+
#
|
51
|
+
# username - The username
|
52
|
+
# password - The password
|
53
|
+
#
|
54
|
+
# Returns true if the username/password pair are authenticated. Will return a falsey value otherwise.
|
49
55
|
def authenticate(username, password)
|
50
|
-
logger.info "Authenticating #{username} (table: #{table_name}, username_field: #{username_field})"
|
56
|
+
logger.info "Authenticating #{username} (table: #{table_name}, username_field: #{username_field})" if logger
|
51
57
|
record = db[table_name].filter(username_field => username).first
|
52
|
-
logger.info "Record found for #{username}"
|
58
|
+
logger.info "Record found for #{username}" if logger
|
53
59
|
tokens = [password, record[salt_field]].compact
|
54
60
|
matches?(record[password_field], *tokens) if record
|
55
61
|
end
|
@@ -1,25 +1,30 @@
|
|
1
1
|
module Zas
|
2
2
|
module CryptoProviders
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# Uses the Sha512 hash algorithm to encrypt passwords.
|
3
|
+
# Public: Uses the Sha512 hash algorithm to encrypt passwords.
|
6
4
|
class Sha512
|
7
5
|
require 'digest/sha2'
|
8
6
|
|
9
|
-
# The number of times to loop through the encryption. This is twenty because that is what restful_authentication defaults to.
|
7
|
+
# Public: The number of times to loop through the encryption. This is twenty because that is what restful_authentication defaults to.
|
10
8
|
def stretches
|
11
9
|
@stretches ||= 20
|
12
10
|
end
|
13
11
|
attr_writer :stretches
|
14
12
|
|
15
|
-
# Turns your raw password into a Sha512 hash.
|
13
|
+
# Public: Turns your raw password into a Sha512 hash.
|
14
|
+
#
|
15
|
+
# tokens - The tokens to encrypt
|
16
|
+
#
|
17
|
+
# Returns the encrypted string
|
16
18
|
def encrypt(*tokens)
|
17
19
|
digest = tokens.flatten.join(nil)
|
18
20
|
stretches.times { digest = Digest::SHA512.hexdigest(digest) }
|
19
21
|
digest
|
20
22
|
end
|
21
23
|
|
22
|
-
# Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
|
24
|
+
# Public: Does the crypted password match the tokens? Uses the same tokens that were used to encrypt.
|
25
|
+
#
|
26
|
+
# crytped - The crypted value
|
27
|
+
# tokens - A collection of tokens to encrypt
|
23
28
|
def matches?(crypted, *tokens)
|
24
29
|
encrypt(*tokens) == crypted
|
25
30
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'base64'
|
2
2
|
module Zas
|
3
3
|
module Filters
|
4
|
-
# Filter that base64 decodes the credentials and splits them
|
4
|
+
# Public: Filter that base64 decodes the credentials and splits them
|
5
5
|
# on a colon (based on the HTTP Basic Authentication
|
6
6
|
# speciications).
|
7
7
|
module HttpBasicAuth
|
8
8
|
module_function
|
9
|
-
# Filter the authentication credentials.
|
9
|
+
# Public: Filter the authentication credentials.
|
10
10
|
#
|
11
11
|
# credentials - The credentials
|
12
12
|
#
|
@@ -1,8 +1,14 @@
|
|
1
1
|
module Zas
|
2
2
|
module Filters
|
3
|
+
# Filter that converts from a Hash to an Array.
|
3
4
|
module StandardAuth
|
4
5
|
module_function
|
5
|
-
|
6
|
+
# Filter the authentication credentials by converting from
|
7
|
+
# a Hash to an array.
|
8
|
+
#
|
9
|
+
# credentials - The credentials Hash
|
10
|
+
#
|
11
|
+
# Returns a pair of [username, password]
|
6
12
|
def authenticate(credentials)
|
7
13
|
[credentials['username'], credentials['password']]
|
8
14
|
end
|
data/lib/zas/service.rb
CHANGED
@@ -4,7 +4,7 @@ require 'yajl'
|
|
4
4
|
require 'hashie'
|
5
5
|
|
6
6
|
module Zas
|
7
|
-
# Authentication service class. Construct a new instance of this
|
7
|
+
# Public: Authentication service class. Construct a new instance of this
|
8
8
|
# class and call the instance method #run to start it.
|
9
9
|
class Service
|
10
10
|
require 'zas/service_configuration'
|
@@ -12,14 +12,17 @@ module Zas
|
|
12
12
|
require 'zas/authenticators'
|
13
13
|
require 'zas/crypto_providers'
|
14
14
|
|
15
|
+
# Public: A syslog logger
|
15
16
|
attr_accessor :logger
|
16
17
|
|
17
|
-
# A collection authenticators mapped to keys.
|
18
|
+
# Public: A collection authenticators mapped to keys.
|
19
|
+
#
|
20
|
+
# Returns a Hash of authenticators.
|
18
21
|
def authenticators
|
19
22
|
@authenticators ||= {}
|
20
23
|
end
|
21
24
|
|
22
|
-
# Initialize the service. The service will not be running yet. Invoke the #run method on the service
|
25
|
+
# Public: Initialize the service. The service will not be running yet. Invoke the #run method on the service
|
23
26
|
# instantce to run the service.
|
24
27
|
#
|
25
28
|
# config - Configuration spec for the service.
|
@@ -30,7 +33,8 @@ module Zas
|
|
30
33
|
self.logger = Syslogger.new(config.name, Syslog::LOG_PID, Syslog::LOG_LOCAL0)
|
31
34
|
end
|
32
35
|
|
33
|
-
# Run the service.
|
36
|
+
# Public: Run the service. This method will block while awaiting incoming requests. The service
|
37
|
+
# may be stopped by sending the INT signal.
|
34
38
|
def run
|
35
39
|
socket = context.socket ZMQ::REP
|
36
40
|
socket.bind "tcp://#{host}:#{port}"
|
@@ -54,7 +58,7 @@ module Zas
|
|
54
58
|
attr_accessor :context
|
55
59
|
attr_writer :logger
|
56
60
|
|
57
|
-
# Handle the authentication.
|
61
|
+
# Internal: Handle the authentication.
|
58
62
|
#
|
59
63
|
# req_string - A JSON string
|
60
64
|
#
|
@@ -63,13 +67,14 @@ module Zas
|
|
63
67
|
req = Hashie::Mash.new(Yajl::Parser.parse(req_string))
|
64
68
|
authenticator = authenticators[req.strategy]
|
65
69
|
raise "No authenticator found for #{req.strategy}" unless authenticator
|
70
|
+
authenticator.logger ||= logger
|
66
71
|
{:authenticated? => authenticator.authenticate(req.credentials)}
|
67
72
|
rescue => e
|
68
73
|
logger.info "Error authenticating: #{e.message}"
|
69
74
|
{:error => e.message}
|
70
75
|
end
|
71
76
|
|
72
|
-
# Encode the response object
|
77
|
+
# Internal: Encode the response object
|
73
78
|
#
|
74
79
|
# data - The object
|
75
80
|
#
|