authd/src/authd.cr

168 lines
2.8 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,
password: String?
})
end
class Client < IPC::Client
property key : String
def initialize
@key = ""
initialize "auth"
end
def get_token?(login : String, password : String)
2019-01-07 17:04:20 +01:00
send RequestTypes::GetToken, {
:login => login,
:password => password
}.to_json
response = read
2018-12-19 13:57:48 +01:00
if response.type == ResponseTypes::Ok.value.to_u8
response.payload
else
nil
end
end
def get_user?(login : String, password : String)
send RequestTypes::GetUserByCredentials, {
:login => login,
:password => password
}.to_json
response = read
if response.type == ResponseTypes::Ok.value.to_u8
User.from_json 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
if response.type == ResponseTypes::Ok.value.to_u8
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)
user, meta = JWT.decode token, @key, "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
pp! response.type
case ResponseTypes.new response.type.to_i
2018-12-19 13:57:48 +01:00
when ResponseTypes::Ok
2018-12-19 13:54:19 +01:00
AuthD::User.from_json response.payload
else
Exception.new response.payload
end
end
2019-05-29 16:06:11 +02:00
def mod_user(uid : Int32, password : String?) : Bool | Exception
payload = Hash(String, String|Int32).new
payload["uid"] = uid
password.try do |password|
payload["password"] = password
end
send RequestTypes::ModUser, payload.to_json
response = read
case ResponseTypes.new response.type.to_i
when ResponseTypes::Ok
true
else
Exception.new response.payload
end
end
end
end