2018-09-22 21:25:03 +02:00
|
|
|
|
|
|
|
require "jwt"
|
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
require "ipc"
|
2018-09-22 21:42:21 +02:00
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
require "./user.cr"
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
module AuthD
|
2019-11-22 17:31:56 +01:00
|
|
|
class Response
|
|
|
|
enum Type
|
|
|
|
Ok
|
|
|
|
Malformed
|
|
|
|
InvalidCredentials
|
|
|
|
InvalidUser
|
|
|
|
UserNotFound # For UID-based GetUser requests.
|
|
|
|
AuthenticationError
|
|
|
|
end
|
2018-11-12 18:51:21 +01:00
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
class Request
|
|
|
|
enum Type
|
|
|
|
GetToken
|
|
|
|
AddUser
|
|
|
|
GetUser
|
|
|
|
GetUserByCredentials
|
|
|
|
ModUser # Edit user attributes.
|
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
class GetToken
|
|
|
|
JSON.mapping({
|
|
|
|
# FIXME: Rename to "login" for consistency.
|
|
|
|
login: String,
|
|
|
|
password: String
|
|
|
|
})
|
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
class AddUser
|
|
|
|
JSON.mapping({
|
|
|
|
# Only clients that have the right shared key will be allowed
|
|
|
|
# to create users.
|
|
|
|
shared_key: String,
|
|
|
|
|
|
|
|
login: String,
|
|
|
|
password: String,
|
|
|
|
uid: Int32?,
|
|
|
|
gid: Int32?,
|
|
|
|
home: String?,
|
|
|
|
shell: String?
|
|
|
|
})
|
|
|
|
end
|
2018-12-19 13:54:19 +01:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
class GetUser
|
|
|
|
JSON.mapping({
|
|
|
|
uid: Int32
|
|
|
|
})
|
|
|
|
end
|
2019-01-07 17:04:20 +01:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
class GetUserByCredentials
|
|
|
|
JSON.mapping({
|
|
|
|
login: String,
|
|
|
|
password: String
|
|
|
|
})
|
|
|
|
end
|
2019-02-16 22:06:56 +01:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
class ModUser
|
|
|
|
JSON.mapping({
|
|
|
|
shared_key: String,
|
2019-10-10 20:58:44 +02:00
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
uid: Int32,
|
|
|
|
password: String?,
|
|
|
|
avatar: String?
|
|
|
|
})
|
|
|
|
end
|
2019-05-29 16:06:11 +02:00
|
|
|
end
|
|
|
|
|
2019-06-05 22:30:29 +02:00
|
|
|
class Client < IPC::Connection
|
2018-11-12 18:51:21 +01:00
|
|
|
property key : String
|
|
|
|
|
|
|
|
def initialize
|
|
|
|
@key = ""
|
|
|
|
|
|
|
|
initialize "auth"
|
2018-09-22 21:25:03 +02:00
|
|
|
end
|
|
|
|
|
2019-06-06 01:16:52 +02:00
|
|
|
def get_token?(login : String, password : String) : String?
|
2019-11-22 17:31:56 +01:00
|
|
|
send Request::Type::GetToken, {
|
2018-12-17 04:39:01 +01:00
|
|
|
:login => login,
|
2018-11-12 18:51:21 +01:00
|
|
|
:password => password
|
|
|
|
}.to_json
|
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
if response.type == Response::Type::Ok.value.to_u8
|
2019-06-06 01:16:52 +02:00
|
|
|
String.new response.payload
|
2018-11-12 18:51:21 +01:00
|
|
|
else
|
|
|
|
nil
|
2018-09-22 21:25:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-11-17 15:50:26 +01:00
|
|
|
def get_user?(login : String, password : String) : Passwd::User?
|
2019-11-22 17:31:56 +01:00
|
|
|
send Request::Type::GetUserByCredentials, {
|
2019-02-16 22:06:56 +01:00
|
|
|
:login => login,
|
|
|
|
:password => password
|
|
|
|
}.to_json
|
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
if response.type == Response::Type::Ok.value.to_u8
|
2019-11-17 15:50:26 +01:00
|
|
|
Passwd::User.from_json String.new response.payload
|
2019-02-16 22:06:56 +01:00
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-07 17:04:20 +01:00
|
|
|
def get_user?(uid : Int32)
|
2019-11-22 17:31:56 +01:00
|
|
|
send Request::Type::GetUser, {:uid => uid}.to_json
|
2019-01-07 17:04:20 +01:00
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
if response.type == Response::Type::Ok.value.to_u8
|
2019-06-29 02:43:31 +02:00
|
|
|
User.from_json String.new response.payload
|
2019-01-07 17:04:20 +01:00
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
def send(type : Request::Type, payload)
|
2018-12-19 13:54:19 +01:00
|
|
|
send type.value.to_u8, payload
|
|
|
|
end
|
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
def decode_token(token)
|
2019-06-28 18:20:34 +02:00
|
|
|
user, meta = JWT.decode token, @key, JWT::Algorithm::HS256
|
2018-11-12 18:51:21 +01:00
|
|
|
|
2019-11-17 15:50:26 +01:00
|
|
|
user = Passwd::User.from_json user.to_json
|
2018-11-12 18:51:21 +01:00
|
|
|
|
|
|
|
{user, meta}
|
|
|
|
end
|
2018-12-19 13:54:19 +01:00
|
|
|
|
|
|
|
# FIXME: Extra options may be useful to implement here.
|
2019-11-17 15:50:26 +01:00
|
|
|
def add_user(login : String, password : String) : Passwd::User | Exception
|
2019-11-22 17:31:56 +01:00
|
|
|
send Request::Type::AddUser, {
|
2019-10-10 20:58:44 +02:00
|
|
|
:shared_key => @key,
|
2018-12-19 13:54:19 +01:00
|
|
|
:login => login,
|
|
|
|
:password => password
|
|
|
|
}.to_json
|
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-06-06 01:16:52 +02:00
|
|
|
payload = String.new response.payload
|
2019-11-22 17:31:56 +01:00
|
|
|
case Response::Type.new response.type.to_i
|
|
|
|
when Response::Type::Ok
|
2019-11-17 15:50:26 +01:00
|
|
|
Passwd::User.from_json payload
|
2018-12-19 13:54:19 +01:00
|
|
|
else
|
2019-06-06 01:16:52 +02:00
|
|
|
Exception.new payload
|
2018-12-19 13:54:19 +01:00
|
|
|
end
|
|
|
|
end
|
2019-05-29 16:06:11 +02:00
|
|
|
|
2019-05-29 19:45:03 +02:00
|
|
|
def mod_user(uid : Int32, password : String? = nil, avatar : String? = nil) : Bool | Exception
|
2019-05-29 16:06:11 +02:00
|
|
|
payload = Hash(String, String|Int32).new
|
|
|
|
payload["uid"] = uid
|
2019-10-10 20:58:44 +02:00
|
|
|
payload["shared_key"] = @key
|
2019-05-29 16:06:11 +02:00
|
|
|
|
|
|
|
password.try do |password|
|
|
|
|
payload["password"] = password
|
|
|
|
end
|
|
|
|
|
2019-05-29 19:45:03 +02:00
|
|
|
avatar.try do |avatar|
|
|
|
|
payload["avatar"] = avatar
|
|
|
|
end
|
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
send Request::Type::ModUser, payload.to_json
|
2019-05-29 16:06:11 +02:00
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-11-22 17:31:56 +01:00
|
|
|
case Response::Type.new response.type.to_i
|
|
|
|
when Response::Type::Ok
|
2019-05-29 16:06:11 +02:00
|
|
|
true
|
|
|
|
else
|
2019-06-06 01:16:52 +02:00
|
|
|
Exception.new String.new response.payload
|
2019-05-29 16:06:11 +02:00
|
|
|
end
|
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|