authd/src/authd.cr

173 lines
3.0 KiB
Crystal
Raw Normal View History

require "jwt"
require "ipc"
require "./user.cr"
require "./group.cr"
module AuthD
enum RequestTypes
2018-12-19 13:57:48 +01:00
GetToken
AddUser
2019-01-07 17:04:20 +01:00
GetUser
GetUserByCredentials
2019-05-29 16:06:11 +02:00
ModUser # Edit user attributes.
end
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.
end
class GetTokenRequest
JSON.mapping({
# FIXME: Rename to "login" for consistency.
login: String,
password: String
})
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
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
property key : String
def initialize
@key = ""
initialize "auth"
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, {
: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
String.new response.payload
else
nil
end
end
2019-06-06 01:16:52 +02:00
def get_user?(login : String, password : String) : User?
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
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-01-07 17:04:20 +01:00
User.from_json response.payload
else
nil
end
end
2018-12-19 13:54:19 +01:00
def send(type : RequestTypes, payload)
send type.value.to_u8, payload
end
def decode_token(token)
2019-06-28 18:20:34 +02:00
user, meta = JWT.decode token, @key, JWT::Algorithm::HS256
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
end
end