Compare commits
10 commits
0ee755f4e9
...
a6add70310
| Author | SHA1 | Date | |
|---|---|---|---|
| a6add70310 | |||
| ecdc3bdc68 | |||
| 43673222df | |||
| 2bfddd1d57 | |||
| 8abe49672b | |||
| 070d49833c | |||
| d325b43c04 | |||
| df2b3f7638 | |||
| 4cd40ef8a6 | |||
| c1304add81 |
28 changed files with 389 additions and 67 deletions
15
apparmor.d/boilerplate
Normal file
15
apparmor.d/boilerplate
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# This file is related to the `Baguette` project (authd, dnsmanagerd…).
|
||||
# It is a way to avoid the long and complex default configuration files provided
|
||||
# by the system. Allowed operations can be known in a matter of seconds.
|
||||
|
||||
# Accept basically all available libraries.
|
||||
@{BASE_LIBS}=/{,usr/,usr/local/}lib{,32,64}/*.so* /usr/lib/x86_64*/*.so* /etc/ld*
|
||||
|
||||
# Enable reading files from different places required by the libraries I use,
|
||||
# which may be the Crystal standard library itself.
|
||||
@{BASE_RO}=/dev/{,u}random /dev/pts/* /proc/** /etc/localtime /usr/share/zoneinfo/**
|
||||
@{BASE_RW}=/dev/{null,zero,full}
|
||||
|
||||
# Found in other profiles:
|
||||
# Recent glibc uses /dev/full in preference to /dev/null for programs
|
||||
# that don't have open fds at exec().
|
||||
27
apparmor.d/dnsmanager
Normal file
27
apparmor.d/dnsmanager
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Main configuration directory.
|
||||
@{MAIN_CONF_DIR}=@{HOME}/.config/baguette
|
||||
|
||||
# Main configuration files.
|
||||
@{AUTHD_CONFIG}=@{MAIN_CONF_DIR}/auth.yml
|
||||
@{DNSMANAGERD_CONFIG}=@{MAIN_CONF_DIR}/dnsmanager.yml
|
||||
|
||||
# Databases.
|
||||
@{AUTHD_DB_PATH}=@{HOME}/tmp/db-authd
|
||||
@{DNSMANAGERD_DB_PATH}=@{HOME}/tmp/db-dnsmanagerd
|
||||
|
||||
# Key to encrypt passwords.
|
||||
@{AUTHD_DB_KEY}=@{MAIN_CONF_DIR}/authd-db-key
|
||||
|
||||
# DNS templates (read-only entries).
|
||||
@{DNSMANAGERD_TEMPLATES}=@{MAIN_CONF_DIR}/templates/*.json
|
||||
|
||||
# Logs.
|
||||
@{LOGS_DIR}=@{HOME}/tmp/logs
|
||||
@{AUTHD_LOGS}=@{LOGS_DIR}/auth
|
||||
@{DNSMANAGERD_LOGS}=@{LOGS_DIR}/dnsmanager
|
||||
|
||||
# Mailer for authd.
|
||||
@{MAILER}=/{usr,usr/local}/bin/mailer
|
||||
|
||||
# IPC-related directory (see libipc(7)).
|
||||
@{LIBIPC_DIR}=/tmp/.libipc-run/
|
||||
33
apparmor.d/usr.local.bin.authd
Normal file
33
apparmor.d/usr.local.bin.authd
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
abi <abi/3.0>,
|
||||
|
||||
include <tunables/global>
|
||||
include <dnsmanager>
|
||||
include <boilerplate>
|
||||
|
||||
/usr/local/bin/authd flags=(enforce) {
|
||||
# See the file `boilerplate`.
|
||||
@{BASE_LIBS} mr,
|
||||
@{BASE_RO} r,
|
||||
@{BASE_RW} rw,
|
||||
|
||||
# Allow IPC-related unix sockets.
|
||||
owner @{LIBIPC_DIR}/* rwk,
|
||||
|
||||
# Enable all unix socket operations. TODO: restrict this even further?
|
||||
unix,
|
||||
|
||||
# Deny networking (udp and tcp).
|
||||
deny network tcp,
|
||||
deny network udp,
|
||||
|
||||
# Enable to read the configuration (and the database key).
|
||||
owner @{AUTHD_CONFIG} r,
|
||||
owner @{AUTHD_DB_KEY} r,
|
||||
|
||||
# Database and logs.
|
||||
owner @{AUTHD_DB_PATH}/** rwkl,
|
||||
owner @{AUTHD_LOGS} w,
|
||||
|
||||
# Enable authd to send mails.
|
||||
@{MAILER} ux,
|
||||
}
|
||||
|
|
@ -4,6 +4,9 @@
|
|||
login: admin
|
||||
pass: secret
|
||||
|
||||
# Path to the log file. By default, everything is just printed on screen.
|
||||
log_file: /var/log/baguette/auth.log
|
||||
|
||||
# In case you have a special `mailer` application.
|
||||
# Read the manual to understand how it is invoked.
|
||||
mailer_exe: /usr/local/bin/my-special-mailer
|
||||
|
|
@ -40,16 +43,10 @@ recovery_template: netlibre-email-recovery
|
|||
|
||||
#verbosity: 4
|
||||
|
||||
# By default, print everything except KEEPALIVE messages.
|
||||
#messages_to_mask: [KEEPALIVE]
|
||||
|
||||
#print_password_recovery_parameters: false
|
||||
|
||||
# IPC-related variables. By default, only print errors and exceptions.
|
||||
#print_ipc_timer: false
|
||||
#print_ipc_connection: false
|
||||
#print_ipc_disconnection: false
|
||||
#print_ipc_extra_socket: false
|
||||
#print_ipc_message_received: false
|
||||
#print_ipc_message_sent: false
|
||||
#print_ipc_switch: false
|
||||
#print_ipc_error: true
|
||||
#print_ipc_exception: true
|
||||
#print_keepalive: false
|
||||
# IPC-related messages. By default, only print errors and exceptions.
|
||||
#ipc_messages_to_show: [ERROR, EXCEPTION]
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ can be:
|
|||
.Bl -tag -width " print functions" -compact
|
||||
.It Li bootstrap
|
||||
Add the first user (an admin).
|
||||
.It Li exit
|
||||
Kill the service.
|
||||
.It Li migration-script
|
||||
Adding a batch of users from old code base.
|
||||
.It Li user
|
||||
|
|
@ -113,7 +115,13 @@ Add the first user (will automatically be an admin).
|
|||
.br
|
||||
.Nm authctl
|
||||
.Ar migration-script No
|
||||
.br
|
||||
|
||||
Kill the service.
|
||||
.br
|
||||
.Nm authctl
|
||||
.Ar exit No
|
||||
.br
|
||||
|
||||
Operations on users.
|
||||
.br
|
||||
|
|
@ -259,13 +267,13 @@ to handle users (authentication, authorization, preferences and profile)
|
|||
.It
|
||||
.Xr mailer 1
|
||||
a simple executable to send mails based on templates
|
||||
.
|
||||
.It
|
||||
.Xr dodb 7
|
||||
a document database library used in
|
||||
.Xr authd .
|
||||
.El
|
||||
|
||||
The Document-oriented DataBase (DoDB) library used in
|
||||
.Xr authd .
|
||||
.br
|
||||
.Lk https://git.baguette.netlib.re/Baguette/dodb.cr dodb
|
||||
|
||||
.Sh Limitations
|
||||
WARNING:
|
||||
.Xr authctl
|
||||
|
|
|
|||
116
man/authd.1
116
man/authd.1
|
|
@ -58,8 +58,8 @@ to encrypt users's password is read from the file
|
|||
.Pa /var/authd/secret-password .
|
||||
.br
|
||||
Finally, indexes are recreated, which is related to the
|
||||
.Xr dodb 7
|
||||
document database, see the related manual page to learn more.
|
||||
.Xr DoDB
|
||||
document database, see the related documentation to learn more.
|
||||
|
||||
.Sh Configuration file variables
|
||||
The following presents the complete list of configuration file variables.
|
||||
|
|
@ -70,50 +70,72 @@ related variables:
|
|||
.
|
||||
.Bl -tag -width " print functions" -compact
|
||||
.It Li ipc_timer
|
||||
Int32, 30_000 (30 seconds)
|
||||
.
|
||||
Int32, 30_000
|
||||
.br
|
||||
The IPC timer wakes the process by default every 30 seconds.
|
||||
There is no much point changing this value since nothing is executed periodically anyway, at least for now.
|
||||
|
||||
.It Li verbosity
|
||||
Int32, 4 ([0-4],
|
||||
Int32, 4
|
||||
.br
|
||||
[0-4],
|
||||
.Dq 0
|
||||
being quiet and
|
||||
.Dq 4
|
||||
meaning printing debug values)
|
||||
.
|
||||
.It Li print functions
|
||||
Print functions enable to select messages to print, for example by printing a message each time a message is received while ignoring keepalive messages.
|
||||
meaning printing debug values.
|
||||
|
||||
.Bl -tag -width " print_ipc_message_received" -compact
|
||||
.It Li print_ipc_timer
|
||||
Bool, false
|
||||
.It Li print_ipc_connection
|
||||
Bool, false
|
||||
.It Li print_ipc_disconnection
|
||||
Bool, false
|
||||
.It Li print_ipc_extra_socket
|
||||
Bool, false
|
||||
.It Li print_ipc_message_received
|
||||
Bool, false
|
||||
.It Li print_ipc_message_sent
|
||||
Bool, false
|
||||
.It Li print_ipc_switch
|
||||
Bool, false
|
||||
.It Li print_ipc_error
|
||||
Bool, true
|
||||
.It Li print_ipc_exception
|
||||
Bool, true
|
||||
.It Li print_keepalive
|
||||
Bool, false
|
||||
.It Li ipc_messages_to_show
|
||||
Array of
|
||||
.Vt Baguette::Configuration::IPC::MESSAGE ,
|
||||
[ERROR, EXCEPTION]
|
||||
|
||||
Types of IPC messages to print, for example all connections.
|
||||
This is mainly for debug since it is very low-level.
|
||||
High-level messages are more relevant to log.
|
||||
By default, errors and exceptions are logged.
|
||||
|
||||
See
|
||||
.Xr Baguette-crystal-base ,
|
||||
which includes the
|
||||
.Vt Baguette::Configuration::IPC::MESSAGE
|
||||
definition.
|
||||
This type has an alias in
|
||||
.Xr authd :
|
||||
.Vt IPCMESSAGE .
|
||||
|
||||
.It Li service_name
|
||||
String,
|
||||
.Dq auth
|
||||
.br
|
||||
.Xr libipc 7
|
||||
unix socket name.
|
||||
.El
|
||||
.
|
||||
.El
|
||||
|
||||
Specific
|
||||
.Xr authd
|
||||
variables:
|
||||
.Bl -tag -width " print_password_recovery_parameters" -compact
|
||||
.It Li service_name
|
||||
String,
|
||||
.Dq auth
|
||||
.Bl -tag -width " print_password_recovery" -compact
|
||||
.It Li log_file
|
||||
String?,
|
||||
.Em none
|
||||
.br
|
||||
Path to the log file.
|
||||
|
||||
.It Li messages_to_mask
|
||||
Array of
|
||||
.Vt AuthD::MESSAGE ,
|
||||
.Em [ KEEPALIVE ]
|
||||
.br
|
||||
List of high-level
|
||||
.Em authd
|
||||
messages to mask in the logs.
|
||||
.br
|
||||
The type
|
||||
.Vt AuthD::MESSAGE
|
||||
has an alias:
|
||||
.Vt AUTHMESSAGE .
|
||||
|
||||
.It Li recreate_indexes
|
||||
Bool, false
|
||||
.It Li storage_directory
|
||||
|
|
@ -250,13 +272,27 @@ to handle users (authentication, authorization, preferences and profile)
|
|||
.It
|
||||
.Xr mailer 1
|
||||
a simple executable to send mails based on templates
|
||||
.
|
||||
.It
|
||||
.Xr dodb 7
|
||||
a document database library used in
|
||||
.Xr authd .
|
||||
.El
|
||||
|
||||
The Document-oriented DataBase (DoDB) library used in
|
||||
.Xr authd .
|
||||
.br
|
||||
.Lk https://git.baguette.netlib.re/Baguette/dodb.cr dodb
|
||||
|
||||
The online service
|
||||
.Dq netlib.re
|
||||
is the first one to use the
|
||||
.Xr authd
|
||||
daemon.
|
||||
.br
|
||||
.Lk https://www.netlib.re netlib.re
|
||||
|
||||
The logging and configuration library for the whole
|
||||
.Dq baguette
|
||||
project.
|
||||
.br
|
||||
.Lk https://git.baguette.netlib.re/Baguette/baguette-crystal-base baguette-crystal-base
|
||||
|
||||
.Sh Limitations
|
||||
WARNING:
|
||||
.Xr authd
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ module AuthD
|
|||
], read
|
||||
end
|
||||
|
||||
def exit
|
||||
send_now Request::Exit.new
|
||||
end
|
||||
|
||||
def validate_user(login : String, activation_key : String)
|
||||
send_now Request::ValidateUser.new login, activation_key
|
||||
parse_message [
|
||||
|
|
|
|||
|
|
@ -79,6 +79,15 @@ parser = OptionParser.new do |parser|
|
|||
unrecognized_args_to_context_args.call parser, 2
|
||||
end
|
||||
|
||||
parser.on "exit", "Kill the service." do
|
||||
parser.banner = "Usage: exit"
|
||||
Baguette::Log.info "Kill the service."
|
||||
Context.command = "exit"
|
||||
opt_authd_login.call parser
|
||||
opt_help.call parser
|
||||
unrecognized_args_to_context_args.call parser, 0
|
||||
end
|
||||
|
||||
parser.on "migration-script", "Add a batch of users from old code base." do
|
||||
parser.banner = "usage: migration-script user-db.txt"
|
||||
Baguette::Log.info "Add a batch of users."
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class Actions
|
|||
@the_call["user-migrate"] = ->user_migrate
|
||||
@the_call["migration-script"] = ->migration_script
|
||||
@the_call["user-mod"] = ->user_mod
|
||||
@the_call["exit"] = ->kill_service
|
||||
|
||||
@the_call["permission-set"] = ->permission_set
|
||||
@the_call["permission-check"] = ->permission_check
|
||||
|
|
@ -192,6 +193,14 @@ class Actions
|
|||
puts "error: #{e.message}"
|
||||
end
|
||||
|
||||
def kill_service
|
||||
puts "Kill the service."
|
||||
authd.exit
|
||||
rescue e : AuthD::Exception
|
||||
puts "error: #{e.message}"
|
||||
end
|
||||
|
||||
|
||||
def user_change_password
|
||||
args = Context.args.not_nil!
|
||||
login = args[0]
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ class IPC::JSON
|
|||
def handle(service : AuthD::Service, fd : Int32)
|
||||
raise "unimplemented"
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
io << self.class.name.sub /[^:]+::[^:]+::/, ""
|
||||
end
|
||||
end
|
||||
|
||||
module AuthD
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ class AuthD::Request
|
|||
def initialize(@login, @password, @admin, @email, @profile)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (login: #{@login}, email: #{@email})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
@ -56,6 +61,11 @@ class AuthD::Request
|
|||
def initialize(@login, @password, @email, @profile = nil)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (login: #{@login}, email: #{email})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
# Check if there already is a registered user.
|
||||
if authd.users.to_a.size > 0
|
||||
|
|
@ -90,6 +100,11 @@ class AuthD::Request
|
|||
def initialize(@token)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (token size: #{@token.size})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
@ -105,4 +120,23 @@ class AuthD::Request
|
|||
end
|
||||
end
|
||||
AuthD.requests << DecodeToken
|
||||
|
||||
IPC::JSON.message Exit, 248 do
|
||||
def initialize
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
logged_user.assert_permission("authd", "*", User::PermissionLevel::Admin)
|
||||
|
||||
Baguette::Log.warning "exit requested, bye"
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
AuthD.requests << Exit
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ class AuthD::Request
|
|||
def initialize(@user = nil)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ class AuthD::Request
|
|||
def initialize(@login, @password)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (login: #{@login})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
begin
|
||||
user = authd.users_per_login.get @login
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ class AuthD::Request
|
|||
def initialize(@login, @password_hash_brkn, @admin = false, @email = nil, @profile = nil)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (login: #{@login}, admin: #{@admin})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ class AuthD::Request
|
|||
def initialize(@user, @admin, @password, @email)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, admin: #{@admin})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ class AuthD::Request
|
|||
def initialize(@login = nil, @email = nil)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (login: #{@login})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
if @login.nil? && @email.nil?
|
||||
return Response::ErrorUserNotFound.new
|
||||
|
|
@ -54,6 +59,11 @@ class AuthD::Request
|
|||
def initialize(@user, @password_renew_key, @new_password)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, password_renew_key: #{@password_renew_key})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
user = authd.user? @user
|
||||
# This is a way for an attacker to know what are the valid logins.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ class AuthD::Request
|
|||
def initialize(@user, @service, @resource)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, service: #{@service}, resource: #{@resource})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
@ -42,6 +47,11 @@ class AuthD::Request
|
|||
def initialize(@user, @service, @resource, @permission)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, service: #{@service}, resource: #{@resource}, permission: #{@permission})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ class AuthD::Request
|
|||
def initialize(@new_profile_entries, @user = nil)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ class AuthD::Request
|
|||
def initialize(@login, @password, @email, @profile)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (login: #{@login})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
unless authd.configuration.registrations
|
||||
return Response::ErrorRegistrationsClosed.new
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ class AuthD::Request
|
|||
def initialize(@regex = nil, @offset = 0)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (regex: #{@regex}, offset: #{@offset})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user_full? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ class AuthD::Request
|
|||
def initialize(@user, @activation_key)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, activation_key: #{@activation_key})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
user = authd.user? @user
|
||||
# This is a way for an attacker to know what are the valid logins.
|
||||
|
|
@ -40,6 +45,11 @@ class AuthD::Request
|
|||
def initialize(@user)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user})"
|
||||
end
|
||||
|
||||
def handle(authd : AuthD::Service, fd : Int32)
|
||||
logged_user = authd.get_logged_user? fd
|
||||
return Response::ErrorMustBeAuthenticated.new if logged_user.nil?
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ class AuthD::Response
|
|||
property email : String? = nil
|
||||
def initialize(@user, @email)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, email: #{@email})"
|
||||
end
|
||||
end
|
||||
|
||||
AuthD.responses << Contacts
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ class AuthD::Response
|
|||
property email : String
|
||||
def initialize(@email)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (email: #{@email})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << NewEmailAddressValidated
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ class AuthD::Response
|
|||
property reason : String? = nil
|
||||
def initialize(@reason)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (reason: #{@reason})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << Error
|
||||
|
||||
|
|
@ -70,6 +75,11 @@ class AuthD::Response
|
|||
property read_only_keys : Array(String)
|
||||
def initialize(@read_only_keys)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (read_only_keys: #{@read_only_keys.join(",")})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << ErrorReadOnlyProfileKeys
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ class AuthD::Response
|
|||
property pending_email : String? = nil
|
||||
def initialize(@token, @uid, @current_email, @pending_email)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (uid: #{@uid})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << Login
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ class AuthD::Response
|
|||
property permission : ::AuthD::User::PermissionLevel
|
||||
def initialize(@service, @resource, @user, @permission)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, service: #{@service}, resource: #{@resource}, permission: #{@permission})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << PermissionCheck
|
||||
|
||||
|
|
@ -16,6 +21,11 @@ class AuthD::Response
|
|||
property permission : ::AuthD::User::PermissionLevel
|
||||
def initialize(@user, @service, @resource, @permission)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user: #{@user}, service: #{@service}, resource: #{@resource}, permission: #{@permission})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << PermissionSet
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ class AuthD::Response
|
|||
property user : ::AuthD::User::Public
|
||||
def initialize(@user)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user public data: #{@user})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << User
|
||||
|
||||
|
|
@ -10,6 +15,11 @@ class AuthD::Response
|
|||
property user : ::AuthD::User::Public
|
||||
def initialize(@user)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user public data: #{@user})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << UserAdded
|
||||
|
||||
|
|
@ -17,6 +27,11 @@ class AuthD::Response
|
|||
property uid : UInt32
|
||||
def initialize(@uid)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (uid: #{@uid})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << UserEdited
|
||||
|
||||
|
|
@ -24,6 +39,11 @@ class AuthD::Response
|
|||
property user : ::AuthD::User::Public
|
||||
def initialize(@user)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (user public data: #{@user})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << UserValidated
|
||||
|
||||
|
|
@ -31,6 +51,11 @@ class AuthD::Response
|
|||
property users : Array(::AuthD::User::Public)
|
||||
def initialize(@users)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (users public data: #{(@users.map &.uid).join ","})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << UsersList
|
||||
|
||||
|
|
@ -38,6 +63,11 @@ class AuthD::Response
|
|||
property users : Array(::AuthD::User::Public)
|
||||
def initialize(@users)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (users public data: #{(@users.map &.uid).join ","})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << MatchingUsers
|
||||
|
||||
|
|
@ -45,6 +75,11 @@ class AuthD::Response
|
|||
property uid : UInt32
|
||||
def initialize(@uid)
|
||||
end
|
||||
|
||||
def to_s(io : IO)
|
||||
super io
|
||||
io << " (uid: #{@uid})"
|
||||
end
|
||||
end
|
||||
AuthD.responses << UserDeleted
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class AuthD::Service < IPC
|
|||
property configuration : Baguette::Configuration::Auth
|
||||
|
||||
# DB and its indexes.
|
||||
property users : DODB::Storage::Cached(User)
|
||||
property users : DODB::Storage::Common(User)
|
||||
property users_per_uid : DODB::Trigger::IndexCached(User)
|
||||
property users_per_login : DODB::Trigger::IndexCached(User)
|
||||
property users_per_email : DODB::Trigger::IndexCached(User)
|
||||
|
|
@ -42,7 +42,7 @@ class AuthD::Service < IPC
|
|||
def initialize(@configuration)
|
||||
super()
|
||||
|
||||
@users = DODB::Storage::Cached(User).new @configuration.storage_directory
|
||||
@users = DODB::Storage::Common(User).new @configuration.storage_directory, 5000
|
||||
@users_per_uid = @users.new_index "uid", &.uid.to_s
|
||||
@users_per_login = @users.new_index "login", &.login
|
||||
@users_per_email = @users.new_index "email" do |user|
|
||||
|
|
@ -111,7 +111,7 @@ class AuthD::Service < IPC
|
|||
File.write @last_uid_file, uid.to_s
|
||||
end
|
||||
|
||||
def get_logged_user?(fd : Int32)
|
||||
def get_logged_user?(fd : Int32) : AuthD::User::Public?
|
||||
@logged_users[fd]?
|
||||
end
|
||||
|
||||
|
|
@ -123,6 +123,17 @@ class AuthD::Service < IPC
|
|||
end
|
||||
end
|
||||
|
||||
# `log_user_info` provides a string composed from either the user
|
||||
# id in case the user was authenticated or the file descriptor of
|
||||
# the connection.
|
||||
def log_user_info(fd : Int32) : String
|
||||
if user = get_logged_user? fd
|
||||
"userid #{user.uid}"
|
||||
else
|
||||
"fd #{"%4d" % fd}"
|
||||
end
|
||||
end
|
||||
|
||||
def user?(uid_or_login : UserID)
|
||||
if uid_or_login.is_a? UInt32
|
||||
@users_per_uid.get? uid_or_login.to_s
|
||||
|
|
@ -144,20 +155,21 @@ class AuthD::Service < IPC
|
|||
end
|
||||
|
||||
request_name = request.class.name.sub /^AuthD::Request::/, ""
|
||||
connection_info_str = log_user_info event.fd
|
||||
|
||||
response = begin
|
||||
request.handle self, event.fd
|
||||
rescue e : UserNotFound
|
||||
Baguette::Log.error "(fd #{ "%4d" % event.fd}) #{request_name} user not found"
|
||||
Baguette::Log.error "(#{connection_info_str}) #{request} user not found"
|
||||
AuthD::Response::Error.new "authorization error"
|
||||
rescue e : AuthenticationInfoLacking
|
||||
Baguette::Log.error "(fd #{ "%4d" % event.fd}) #{request_name} lacking authentication info"
|
||||
Baguette::Log.error "(#{connection_info_str}) #{request} lacking authentication info"
|
||||
AuthD::Response::Error.new "authorization error"
|
||||
rescue e : AdminAuthorizationException
|
||||
Baguette::Log.error "(fd #{ "%4d" % event.fd}) #{request_name} admin authentication failed"
|
||||
Baguette::Log.error "(#{connection_info_str}) #{request} admin authentication failed"
|
||||
AuthD::Response::Error.new "authorization error"
|
||||
rescue e
|
||||
Baguette::Log.error "(fd #{ "%4d" % event.fd}) #{request_name} generic error #{e}"
|
||||
Baguette::Log.error "(#{connection_info_str}) #{request} generic error #{e}"
|
||||
AuthD::Response::Error.new "unknown error"
|
||||
end
|
||||
|
||||
|
|
@ -169,13 +181,11 @@ class AuthD::Service < IPC
|
|||
|
||||
duration = Time.utc - request_start
|
||||
|
||||
response_name = response.class.name.sub /^AuthD::Response::/, ""
|
||||
|
||||
if response.is_a? AuthD::Response::Error
|
||||
Baguette::Log.warning "fd #{ "%4d" % event.fd} (#{duration}) #{request_name} >> #{response_name} (#{response.reason})"
|
||||
Baguette::Log.warning "(#{connection_info_str}) (#{duration}) #{request} >> #{response}"
|
||||
else
|
||||
if request_name != "KeepAlive" || should_display? AUTHMESSAGE::KEEPALIVE
|
||||
Baguette::Log.debug "fd #{ "%4d" % event.fd} (#{duration}) #{request_name} >> #{response_name}"
|
||||
Baguette::Log.debug "(#{connection_info_str}) (#{duration}) #{request} >> #{response}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue