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-12-17 00:56:03 +01:00
|
|
|
require "./group.cr"
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
module AuthD
|
|
|
|
enum RequestTypes
|
2018-12-19 13:57:48 +01:00
|
|
|
GetToken
|
|
|
|
AddUser
|
2019-01-07 17:04:20 +01:00
|
|
|
GetUser
|
2019-02-16 22:06:56 +01:00
|
|
|
GetUserByCredentials
|
2019-05-29 16:06:11 +02:00
|
|
|
ModUser # Edit user attributes.
|
2018-11-12 18:51:21 +01:00
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
enum ResponseTypes
|
2018-12-19 13:57:48 +01:00
|
|
|
Ok
|
|
|
|
MalformedRequest
|
|
|
|
InvalidCredentials
|
|
|
|
InvalidUser
|
2019-01-07 17:04:20 +01:00
|
|
|
UserNotFound # For UID-based GetUser requests.
|
2018-11-12 18:51:21 +01:00
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
2018-11-12 18:51:21 +01:00
|
|
|
class GetTokenRequest
|
|
|
|
JSON.mapping({
|
2018-12-17 00:56:03 +01:00
|
|
|
# FIXME: Rename to "login" for consistency.
|
2018-12-17 04:39:01 +01:00
|
|
|
login: String,
|
2018-11-12 18:51:21 +01:00
|
|
|
password: String
|
|
|
|
})
|
2018-09-22 21:25:03 +02:00
|
|
|
end
|
|
|
|
|
2018-12-19 13:54:19 +01:00
|
|
|
class AddUserRequest
|
|
|
|
JSON.mapping({
|
|
|
|
login: String,
|
|
|
|
password: String,
|
|
|
|
uid: Int32?,
|
|
|
|
gid: Int32?,
|
|
|
|
home: String?,
|
|
|
|
shell: String?
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2019-01-07 17:04:20 +01:00
|
|
|
class GetUserRequest
|
|
|
|
JSON.mapping({
|
|
|
|
uid: Int32
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2019-02-16 22:06:56 +01:00
|
|
|
class GetUserByCredentialsRequest
|
|
|
|
JSON.mapping({
|
|
|
|
login: String,
|
|
|
|
password: String
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
2019-05-29 16:06:11 +02:00
|
|
|
class ModUserRequest
|
|
|
|
JSON.mapping({
|
|
|
|
uid: Int32,
|
2019-05-29 19:45:03 +02:00
|
|
|
password: String?,
|
|
|
|
avatar: String?
|
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-01-07 17:04:20 +01:00
|
|
|
send RequestTypes::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-06-05 22:38:08 +02:00
|
|
|
if response.type == ResponseTypes::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-06-06 01:16:52 +02:00
|
|
|
def get_user?(login : String, password : String) : User?
|
2019-02-16 22:06:56 +01:00
|
|
|
send RequestTypes::GetUserByCredentials, {
|
|
|
|
:login => login,
|
|
|
|
:password => password
|
|
|
|
}.to_json
|
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-06-05 22:38:08 +02:00
|
|
|
if response.type == ResponseTypes::Ok.value.to_u8
|
2019-06-06 01:16:52 +02:00
|
|
|
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)
|
|
|
|
send RequestTypes::GetUser, {:uid => uid}.to_json
|
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-06-05 22:38:08 +02:00
|
|
|
if response.type == ResponseTypes::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
|
|
|
|
|
2018-12-19 13:54:19 +01:00
|
|
|
def send(type : RequestTypes, payload)
|
|
|
|
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
|
|
|
|
|
|
|
user = AuthD::User.from_json user.to_json
|
|
|
|
|
|
|
|
{user, meta}
|
|
|
|
end
|
2018-12-19 13:54:19 +01:00
|
|
|
|
|
|
|
# FIXME: Extra options may be useful to implement here.
|
|
|
|
def add_user(login : String, password : String) : AuthD::User | Exception
|
2018-12-19 13:57:48 +01:00
|
|
|
send RequestTypes::AddUser, {
|
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-06-05 22:38:08 +02:00
|
|
|
case ResponseTypes.new response.type.to_i
|
2018-12-19 13:57:48 +01:00
|
|
|
when ResponseTypes::Ok
|
2019-06-06 01:16:52 +02:00
|
|
|
AuthD::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
|
|
|
|
|
|
|
|
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-05-29 16:06:11 +02:00
|
|
|
send RequestTypes::ModUser, payload.to_json
|
|
|
|
|
|
|
|
response = read
|
|
|
|
|
2019-06-05 22:38:08 +02:00
|
|
|
case ResponseTypes.new response.type.to_i
|
2019-05-29 16:06:11 +02:00
|
|
|
when ResponseTypes::Ok
|
|
|
|
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
|
|
|
|
|