authd/src/authd/client.cr

255 lines
6.0 KiB
Crystal
Raw Normal View History

2020-11-26 04:02:19 +01:00
require "ipc/json"
require "json"
2020-11-22 13:49:34 +01:00
module AuthD
class Client < IPC
2020-11-22 13:49:34 +01:00
property key : String
property server_fd : Int32 = -1
2020-11-22 13:49:34 +01:00
def initialize
super
2020-11-22 13:49:34 +01:00
@key = ""
fd = self.connect "auth"
if fd.nil?
raise "couldn't connect to 'auth' IPC service"
end
@server_fd = fd
end
2020-11-22 13:49:34 +01:00
def read
slice = self.read @server_fd
m = IPCMessage::TypedMessage.deserialize slice
m.not_nil!
2020-11-22 13:49:34 +01:00
end
def get_token?(login : String, password : String) : String?
send_now Request::Login.new login, password
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
if response.is_a?(Response::Login)
2020-11-22 13:49:34 +01:00
response.token
else
nil
end
end
def get_user?(login : String, password : String) : AuthD::User::Public?
2020-11-26 04:02:19 +01:00
send_now Request::GetUserByCredentials.new login, password
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
if response.is_a? Response::User
response.user
else
nil
end
end
def get_user?(uid_or_login : Int32 | String) : ::AuthD::User::Public?
2020-11-26 04:02:19 +01:00
send_now Request::GetUser.new uid_or_login
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
if response.is_a? Response::User
response.user
else
nil
end
end
def send_now(msg : IPC::JSON)
m = IPCMessage::TypedMessage.new msg.type.to_u8, msg.to_json
write @server_fd, m
end
2020-11-26 04:02:19 +01:00
def send_now(type : Request::Type, payload)
m = IPCMessage::TypedMessage.new type.value.to_u8, payload
write @server_fd, m
2020-11-22 13:49:34 +01:00
end
def decode_token(token)
user, meta = JWT.decode token, @key, JWT::Algorithm::HS256
user = ::AuthD::User::Public.from_json user.to_json
{user, meta}
end
# FIXME: Extra options may be useful to implement here.
def add_user(login : String, password : String,
admin : Bool,
2020-11-22 13:49:34 +01:00
email : String?,
profile : Hash(String, ::JSON::Any)?) : ::AuthD::User::Public | Exception
2020-11-22 13:49:34 +01:00
send_now Request::AddUser.new login, password, admin, email, profile
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::UserAdded
response.user
when Response::Error
raise Exception.new response.reason
else
# Should not happen in serialized connections, but…
# itll happen if you run several requests at once.
Exception.new
end
end
def validate_user(login : String, activation_key : String) : ::AuthD::User::Public | Exception
2020-11-26 04:02:19 +01:00
send_now Request::ValidateUser.new login, activation_key
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::UserValidated
response.user
when Response::Error
raise Exception.new response.reason
else
# Should not happen in serialized connections, but…
# itll happen if you run several requests at once.
Exception.new
end
end
def ask_password_recovery(uid_or_login : String | Int32)
send_now Request::AskPasswordRecovery.new uid_or_login
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::PasswordRecoverySent
when Response::Error
raise Exception.new response.reason
else
Exception.new
end
end
def change_password(uid_or_login : String | Int32, new_pass : String, renew_key : String)
2020-11-26 04:02:19 +01:00
send_now Request::PasswordRecovery.new uid_or_login, renew_key, new_pass
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::PasswordRecovered
when Response::Error
raise Exception.new response.reason
else
Exception.new
end
end
def register(login : String,
password : String,
email : String?,
profile : Hash(String, ::JSON::Any)?) : ::AuthD::User::Public?
2020-11-22 13:49:34 +01:00
send_now Request::Register.new login, password, email, profile
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::UserAdded
when Response::Error
raise Exception.new response.reason
end
end
def mod_user(uid_or_login : Int32 | String, password : String? = nil, email : String? = nil) : Bool | Exception
request = Request::ModUser.new uid_or_login
2020-11-22 13:49:34 +01:00
request.password = password if password
request.email = email if email
2020-11-26 04:02:19 +01:00
send_now request
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::UserEdited
true
when Response::Error
Exception.new response.reason
else
Exception.new "???"
end
end
def check_permission(user : Int32, service_name : String, resource_name : String) : User::PermissionLevel
request = Request::CheckPermission.new user, service_name, resource_name
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
send_now request
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::PermissionCheck
response.permission
when Response
raise Exception.new "unexpected response: #{response.type}"
else
raise Exception.new "unexpected response"
end
end
def set_permission(uid : Int32, service : String, resource : String, permission : User::PermissionLevel)
request = Request::SetPermission.new uid, service, resource, permission
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
send_now request
2020-11-22 13:49:34 +01:00
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::PermissionSet
true
when Response
raise Exception.new "unexpected response: #{response.type}"
else
raise Exception.new "unexpected response"
end
end
def search_user(user_login : String)
2020-11-26 04:02:19 +01:00
send_now Request::SearchUser.new user_login
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::MatchingUsers
response.users
when Response::Error
raise Exception.new response.reason
else
Exception.new
end
end
def edit_profile_content(user : Int32 | String, new_values)
send_now Request::EditProfileEntries.new user, new_values
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::User
response.user
when Response::Error
raise Exception.new response.reason
else
raise Exception.new "unexpected response"
end
end
def delete(user : Int32 | String)
send_now Request::Delete.new user
2020-11-22 13:49:34 +01:00
delete_
end
def delete_
2020-11-26 04:02:19 +01:00
response = AuthD.responses.parse_ipc_json read
2020-11-22 13:49:34 +01:00
case response
when Response::Error
raise Exception.new response.reason
end
response
end
end
end