authd/src/main.cr

158 lines
3.5 KiB
Crystal
Raw Normal View History

2018-09-22 19:08:28 +02:00
require "uuid"
require "option_parser"
2019-02-19 20:45:19 +01:00
require "openssl"
2018-09-22 19:08:28 +02:00
require "jwt"
2019-11-17 15:56:35 +01:00
require "passwd"
require "ipc"
require "./authd.cr"
extend AuthD
2019-06-05 22:30:29 +02:00
class IPC::Connection
2019-11-22 17:31:56 +01:00
def send(type : AuthD::Response::Type, payload : String)
2019-06-05 22:30:29 +02:00
send type.to_u8, payload
2018-12-19 13:54:19 +01:00
end
end
authd_passwd_file = "passwd"
authd_group_file = "group"
2018-09-22 19:46:48 +02:00
authd_jwt_key = "nico-nico-nii"
2018-09-22 19:08:28 +02:00
OptionParser.parse do |parser|
parser.on "-u file", "--passwd-file file", "passwd file." do |name|
authd_passwd_file = name
2018-09-22 19:08:28 +02:00
end
parser.on "-g file", "--group-file file", "group file." do |name|
authd_group_file = name
2018-09-22 19:46:48 +02:00
end
parser.on "-K file", "--key-file file", "JWT key file" do |file_name|
authd_jwt_key = File.read(file_name).chomp
2018-09-22 19:08:28 +02:00
end
parser.on "-h", "--help", "Show this help" do
puts parser
2018-09-22 19:08:28 +02:00
exit 0
2018-09-22 19:08:28 +02:00
end
end
passwd = Passwd.new authd_passwd_file, authd_group_file
##
# Provides a JWT-based authentication scheme for service-specific users.
IPC::Service.new "auth" do |event|
2019-06-05 22:30:29 +02:00
if event.is_a? IPC::Exception
puts "oh no"
pp! event
next
end
case event
when IPC::Event::Message
2019-11-03 13:17:24 +01:00
client = event.connection
message = event.message
payload = message.payload
2019-11-22 17:31:56 +01:00
case Request::Type.new message.type.to_i
when Request::Type::GetToken
begin
2019-11-22 17:31:56 +01:00
request = Request::GetToken.from_json String.new payload
rescue e
2019-11-22 17:31:56 +01:00
client.send Response::Type::Malformed.value.to_u8, e.message || ""
next
end
user = passwd.get_user request.login, request.password
if user.nil?
2019-11-22 17:31:56 +01:00
client.send Response::Type::InvalidCredentials.value.to_u8, ""
next
end
2019-11-22 17:31:56 +01:00
client.send Response::Type::Ok.value.to_u8,
2019-06-28 18:20:34 +02:00
JWT.encode user.to_h, authd_jwt_key, JWT::Algorithm::HS256
2019-11-22 17:31:56 +01:00
when Request::Type::AddUser
2018-12-19 13:54:19 +01:00
begin
2019-11-22 17:31:56 +01:00
request = Request::AddUser.from_json String.new payload
2018-12-19 13:54:19 +01:00
rescue e
2019-11-22 17:31:56 +01:00
client.send Response::Type::Malformed.value.to_u8, e.message || ""
2018-12-19 13:54:19 +01:00
next
end
if request.shared_key != authd_jwt_key
2019-11-22 17:31:56 +01:00
client.send Response::Type::AuthenticationError, "Invalid authentication key."
next
end
2018-12-19 13:54:19 +01:00
if passwd.user_exists? request.login
2019-11-22 17:31:56 +01:00
client.send Response::Type::InvalidUser, "Another user with the same login already exists."
2018-12-19 13:54:19 +01:00
next
end
user = passwd.add_user request.login, request.password
2019-11-22 17:31:56 +01:00
client.send Response::Type::Ok, user.sanitize!.to_json
when Request::Type::GetUserByCredentials
begin
2019-11-22 17:31:56 +01:00
request = Request::GetUserByCredentials.from_json String.new payload
rescue e
2019-11-22 17:31:56 +01:00
client.send Response::Type::Malformed, e.message || ""
next
end
user = passwd.get_user request.login, request.password
if user
2019-11-22 17:31:56 +01:00
client.send Response::Type::Ok, user.sanitize!.to_json
else
2019-11-22 17:31:56 +01:00
client.send Response::Type::UserNotFound, ""
end
2019-11-22 17:31:56 +01:00
when Request::Type::GetUser
2019-01-07 17:04:20 +01:00
begin
2019-11-22 17:31:56 +01:00
request = Request::GetUser.from_json String.new payload
2019-01-07 17:04:20 +01:00
rescue e
2019-11-22 17:31:56 +01:00
client.send Response::Type::Malformed, e.message || ""
2019-01-07 17:04:20 +01:00
next
end
user = passwd.get_user request.uid
if user
2019-11-22 17:31:56 +01:00
client.send Response::Type::Ok, user.sanitize!.to_json
2019-01-07 17:04:20 +01:00
else
2019-11-22 17:31:56 +01:00
client.send Response::Type::UserNotFound, ""
2019-01-07 17:04:20 +01:00
end
2019-11-22 17:31:56 +01:00
when Request::Type::ModUser
2019-05-29 16:06:11 +02:00
begin
2019-11-22 17:31:56 +01:00
request = Request::ModUser.from_json String.new payload
2019-05-29 16:06:11 +02:00
rescue e
2019-11-22 17:31:56 +01:00
client.send Response::Type::Malformed, e.message || ""
2019-05-29 16:06:11 +02:00
next
end
if request.shared_key != authd_jwt_key
2019-11-22 17:31:56 +01:00
client.send Response::Type::AuthenticationError, "Invalid authentication key."
next
end
2019-05-29 16:06:11 +02:00
password_hash = request.password.try do |s|
Passwd.hash_password s
end
passwd.mod_user request.uid, password_hash: password_hash
2019-05-29 16:06:11 +02:00
2019-11-22 17:31:56 +01:00
client.send Response::Type::Ok, ""
end
end
2018-09-22 19:08:28 +02:00
end