2019-11-22 18:14:52 +01:00
|
|
|
|
require "json"
|
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
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
class AuthD::Exception < Exception
|
|
|
|
|
end
|
|
|
|
|
|
2020-02-26 14:54:14 +01:00
|
|
|
|
class AuthD::MalformedRequest < Exception
|
|
|
|
|
getter ipc_type : Int32
|
|
|
|
|
getter payload : String
|
|
|
|
|
|
|
|
|
|
def initialize(@ipc_type, @payload)
|
|
|
|
|
@message = "malformed payload"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
class AuthD::Response
|
|
|
|
|
include JSON::Serializable
|
|
|
|
|
|
|
|
|
|
annotation MessageType
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class_getter type = -1
|
2019-11-22 23:13:34 +01:00
|
|
|
|
def type
|
|
|
|
|
@@type
|
|
|
|
|
end
|
2019-11-22 22:55:12 +01:00
|
|
|
|
|
|
|
|
|
macro inherited
|
|
|
|
|
def self.type
|
|
|
|
|
::AuthD::Response::Type::{{ @type.name.split("::").last.id }}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
macro initialize(*properties)
|
|
|
|
|
def initialize(
|
|
|
|
|
{% for value in properties %}
|
|
|
|
|
@{{value.id}}{% if value != properties.last %},{% end %}
|
|
|
|
|
{% end %}
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def type
|
|
|
|
|
Type::{{ @type.name.split("::").last.id }}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class Error < Response
|
|
|
|
|
property reason : String?
|
|
|
|
|
|
|
|
|
|
initialize :reason
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class Token < Response
|
2020-04-25 10:34:07 +02:00
|
|
|
|
property uid : Int32
|
2019-11-22 22:55:12 +01:00
|
|
|
|
property token : String
|
|
|
|
|
|
2020-04-25 10:34:07 +02:00
|
|
|
|
initialize :token, :uid
|
2019-11-22 22:55:12 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class User < Response
|
2019-12-15 23:38:49 +01:00
|
|
|
|
property user : ::AuthD::User::Public
|
2019-11-22 22:55:12 +01:00
|
|
|
|
|
|
|
|
|
initialize :user
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class UserAdded < Response
|
2019-12-15 23:38:49 +01:00
|
|
|
|
property user : ::AuthD::User::Public
|
2019-11-22 22:55:12 +01:00
|
|
|
|
|
|
|
|
|
initialize :user
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class UserEdited < Response
|
|
|
|
|
property uid : Int32
|
|
|
|
|
|
|
|
|
|
initialize :uid
|
|
|
|
|
end
|
|
|
|
|
|
2020-01-22 10:13:59 +01:00
|
|
|
|
class UserValidated < Response
|
2020-01-22 14:43:58 +01:00
|
|
|
|
property user : ::AuthD::User::Public
|
2020-01-22 10:13:59 +01:00
|
|
|
|
|
2020-01-22 14:43:58 +01:00
|
|
|
|
initialize :user
|
2020-01-22 10:13:59 +01:00
|
|
|
|
end
|
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
class UsersList < Response
|
|
|
|
|
property users : Array(::AuthD::User::Public)
|
2019-12-07 21:09:17 +01:00
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
initialize :users
|
2019-12-07 21:09:17 +01:00
|
|
|
|
end
|
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
class PermissionCheck < Response
|
|
|
|
|
property user : Int32
|
|
|
|
|
property service : String
|
|
|
|
|
property resource : String
|
|
|
|
|
property permission : ::AuthD::User::PermissionLevel
|
2019-12-07 21:09:17 +01:00
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
initialize :service, :resource, :user, :permission
|
2019-12-07 21:09:17 +01:00
|
|
|
|
end
|
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
class PermissionSet < Response
|
|
|
|
|
property user : Int32
|
|
|
|
|
property service : String
|
|
|
|
|
property resource : String
|
|
|
|
|
property permission : ::AuthD::User::PermissionLevel
|
2019-12-09 21:57:38 +01:00
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
initialize :user, :service, :resource, :permission
|
2019-12-09 21:57:38 +01:00
|
|
|
|
end
|
|
|
|
|
|
2020-02-23 20:37:50 +01:00
|
|
|
|
class PasswordRecoverySent < Response
|
|
|
|
|
property user : ::AuthD::User::Public
|
|
|
|
|
|
|
|
|
|
initialize :user
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class PasswordRecovered < Response
|
|
|
|
|
property user : ::AuthD::User::Public
|
|
|
|
|
|
|
|
|
|
initialize :user
|
|
|
|
|
end
|
|
|
|
|
|
2020-03-23 15:06:54 +01:00
|
|
|
|
class MatchingUsers < Response
|
|
|
|
|
property users : Array(::AuthD::User::Public)
|
|
|
|
|
|
|
|
|
|
initialize :users
|
|
|
|
|
end
|
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
# This creates a Request::Type enumeration. One entry for each request type.
|
|
|
|
|
{% begin %}
|
2019-11-22 17:31:56 +01:00
|
|
|
|
enum Type
|
2019-11-22 22:55:12 +01:00
|
|
|
|
{% for ivar in @type.subclasses %}
|
|
|
|
|
{% klass = ivar.name %}
|
|
|
|
|
{% name = ivar.name.split("::").last.id %}
|
|
|
|
|
|
|
|
|
|
{% a = ivar.annotation(MessageType) %}
|
|
|
|
|
|
|
|
|
|
{% if a %}
|
|
|
|
|
{% value = a[0] %}
|
|
|
|
|
{{ name }} = {{ value }}
|
|
|
|
|
{% else %}
|
|
|
|
|
{{ name }}
|
|
|
|
|
{% end %}
|
|
|
|
|
{% end %}
|
2019-11-22 17:31:56 +01:00
|
|
|
|
end
|
2019-11-22 22:55:12 +01:00
|
|
|
|
{% end %}
|
|
|
|
|
|
|
|
|
|
# This is an array of all requests types.
|
|
|
|
|
{% begin %}
|
|
|
|
|
class_getter requests = [
|
|
|
|
|
{% for ivar in @type.subclasses %}
|
|
|
|
|
{% klass = ivar.name %}
|
|
|
|
|
|
|
|
|
|
{{klass}},
|
|
|
|
|
{% end %}
|
|
|
|
|
]
|
|
|
|
|
{% end %}
|
|
|
|
|
|
2019-11-23 01:08:05 +01:00
|
|
|
|
def self.from_ipc(message : IPC::Message) : Response?
|
2019-11-22 22:55:12 +01:00
|
|
|
|
payload = String.new message.payload
|
2020-02-06 10:20:57 +01:00
|
|
|
|
type = Type.new message.utype.to_i
|
2019-11-22 22:55:12 +01:00
|
|
|
|
|
2020-02-26 14:54:14 +01:00
|
|
|
|
begin
|
|
|
|
|
requests.find(&.type.==(type)).try &.from_json(payload)
|
|
|
|
|
rescue e : JSON::ParseException
|
|
|
|
|
raise MalformedRequest.new message.utype.to_i, payload
|
|
|
|
|
end
|
2019-11-22 22:55:12 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
class AuthD::Request
|
|
|
|
|
include JSON::Serializable
|
2018-09-22 21:25:03 +02:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
annotation MessageType
|
|
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
class_getter type = -1
|
|
|
|
|
|
|
|
|
|
macro inherited
|
|
|
|
|
def self.type
|
|
|
|
|
::AuthD::Request::Type::{{ @type.name.split("::").last.id }}
|
2019-11-22 17:31:56 +01:00
|
|
|
|
end
|
2019-11-22 18:14:52 +01:00
|
|
|
|
end
|
2018-12-19 13:54:19 +01:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
macro initialize(*properties)
|
|
|
|
|
def initialize(
|
|
|
|
|
{% for value in properties %}
|
|
|
|
|
@{{value.id}}{% if value != properties.last %},{% end %}
|
|
|
|
|
{% end %}
|
|
|
|
|
)
|
2019-11-22 17:31:56 +01:00
|
|
|
|
end
|
2019-01-07 17:04:20 +01:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
def type
|
|
|
|
|
Type::{{ @type.name.split("::").last.id }}
|
2019-11-22 17:31:56 +01:00
|
|
|
|
end
|
2019-11-22 18:14:52 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class GetToken < Request
|
|
|
|
|
property login : String
|
|
|
|
|
property password : String
|
|
|
|
|
|
|
|
|
|
initialize :login, :password
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class AddUser < Request
|
|
|
|
|
# Only clients that have the right shared key will be allowed
|
|
|
|
|
# to create users.
|
|
|
|
|
property shared_key : String
|
|
|
|
|
|
|
|
|
|
property login : String
|
|
|
|
|
property password : String
|
2020-01-22 01:55:57 +01:00
|
|
|
|
property email : String?
|
|
|
|
|
property phone : String?
|
2020-08-10 23:45:44 +02:00
|
|
|
|
property profile : Hash(String, JSON::Any)?
|
2019-11-22 18:14:52 +01:00
|
|
|
|
|
2020-01-22 01:55:57 +01:00
|
|
|
|
initialize :shared_key, :login, :password, :email, :phone, :profile
|
2019-11-22 18:14:52 +01:00
|
|
|
|
end
|
|
|
|
|
|
2020-01-22 10:13:59 +01:00
|
|
|
|
class ValidateUser < Request
|
2020-01-22 14:43:58 +01:00
|
|
|
|
property login : String
|
2020-01-22 10:13:59 +01:00
|
|
|
|
property activation_key : String
|
|
|
|
|
|
2020-04-03 16:42:45 +02:00
|
|
|
|
initialize :login, :activation_key
|
2020-01-22 10:13:59 +01:00
|
|
|
|
end
|
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
class GetUser < Request
|
2019-12-15 23:38:49 +01:00
|
|
|
|
property user : Int32 | String
|
2019-11-22 18:14:52 +01:00
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
initialize :user
|
2019-11-22 18:14:52 +01:00
|
|
|
|
end
|
2019-02-16 22:06:56 +01:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
class GetUserByCredentials < Request
|
|
|
|
|
property login : String
|
|
|
|
|
property password : String
|
2019-10-10 20:58:44 +02:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
initialize :login, :password
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class ModUser < Request
|
|
|
|
|
property shared_key : String
|
|
|
|
|
|
2020-02-09 15:47:44 +01:00
|
|
|
|
property user : Int32 | String
|
2019-11-22 18:14:52 +01:00
|
|
|
|
property password : String?
|
2020-02-09 15:47:44 +01:00
|
|
|
|
property email : String?
|
|
|
|
|
property phone : String?
|
2019-11-22 18:14:52 +01:00
|
|
|
|
property avatar : String?
|
|
|
|
|
|
2020-02-09 15:47:44 +01:00
|
|
|
|
initialize :shared_key, :user
|
2019-11-22 18:14:52 +01:00
|
|
|
|
end
|
|
|
|
|
|
2019-12-07 00:53:31 +01:00
|
|
|
|
class Request::Register < Request
|
|
|
|
|
property login : String
|
|
|
|
|
property password : String
|
2020-01-22 01:55:57 +01:00
|
|
|
|
property email : String?
|
|
|
|
|
property phone : String?
|
2020-08-10 23:45:44 +02:00
|
|
|
|
property profile : Hash(String, JSON::Any)?
|
2019-12-07 00:53:31 +01:00
|
|
|
|
|
2020-01-22 01:55:57 +01:00
|
|
|
|
initialize :login, :password, :email, :phone, :profile
|
2019-12-07 21:09:17 +01:00
|
|
|
|
end
|
|
|
|
|
|
2019-12-07 23:57:40 +01:00
|
|
|
|
class Request::UpdatePassword < Request
|
|
|
|
|
property login : String
|
|
|
|
|
property old_password : String
|
|
|
|
|
property new_password : String
|
|
|
|
|
end
|
|
|
|
|
|
2019-12-09 21:57:38 +01:00
|
|
|
|
class Request::ListUsers < Request
|
|
|
|
|
property token : String?
|
|
|
|
|
property key : String?
|
|
|
|
|
end
|
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
class CheckPermission < Request
|
|
|
|
|
property shared_key : String
|
|
|
|
|
|
|
|
|
|
# FIXME: Make it Int32 | String
|
|
|
|
|
property user : Int32
|
|
|
|
|
property service : String
|
|
|
|
|
property resource : String
|
|
|
|
|
|
|
|
|
|
initialize :shared_key, :user, :service, :resource
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class SetPermission < Request
|
|
|
|
|
property shared_key : String
|
|
|
|
|
|
|
|
|
|
# FIXME: Make it Int32 | String
|
|
|
|
|
property user : Int32
|
|
|
|
|
property service : String
|
|
|
|
|
property resource : String
|
|
|
|
|
property permission : ::AuthD::User::PermissionLevel
|
|
|
|
|
|
|
|
|
|
initialize :shared_key, :user, :service, :resource, :permission
|
|
|
|
|
end
|
|
|
|
|
|
2020-02-23 20:37:50 +01:00
|
|
|
|
class PasswordRecovery < Request
|
|
|
|
|
property shared_key : String
|
|
|
|
|
property user : Int32 | String
|
|
|
|
|
property password_renew_key : String
|
|
|
|
|
property new_password : String
|
|
|
|
|
|
|
|
|
|
initialize :shared_key, :user, :password_renew_key, :new_password
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class AskPasswordRecovery < Request
|
|
|
|
|
property user : Int32 | String
|
|
|
|
|
|
|
|
|
|
initialize :user
|
|
|
|
|
end
|
|
|
|
|
|
2020-03-23 15:06:54 +01:00
|
|
|
|
class SearchUser < Request
|
|
|
|
|
property user : String
|
|
|
|
|
|
|
|
|
|
initialize :user
|
|
|
|
|
end
|
|
|
|
|
|
2020-04-18 21:21:17 +02:00
|
|
|
|
class EditProfile < Request
|
|
|
|
|
property token : String
|
2020-08-10 23:45:44 +02:00
|
|
|
|
property new_profile : Hash(String, JSON::Any)
|
2020-04-18 21:21:17 +02:00
|
|
|
|
|
|
|
|
|
initialize :token, :new_profile
|
|
|
|
|
end
|
|
|
|
|
|
2020-08-10 23:45:44 +02:00
|
|
|
|
# Same as above, but doesn’t reset the whole profile, only resets elements
|
|
|
|
|
# for which keys are present in `new_profile`.
|
|
|
|
|
class EditProfileContent < Request
|
|
|
|
|
property token : String?
|
|
|
|
|
|
|
|
|
|
property shared_key : String?
|
|
|
|
|
property user : Int32 | String | Nil
|
|
|
|
|
|
|
|
|
|
property new_profile : Hash(String, JSON::Any)
|
|
|
|
|
|
|
|
|
|
initialize :shared_key, :user, :new_profile
|
|
|
|
|
initialize :token, :new_profile
|
|
|
|
|
end
|
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
# This creates a Request::Type enumeration. One entry for each request type.
|
|
|
|
|
{% begin %}
|
|
|
|
|
enum Type
|
|
|
|
|
{% for ivar in @type.subclasses %}
|
|
|
|
|
{% klass = ivar.name %}
|
|
|
|
|
{% name = ivar.name.split("::").last.id %}
|
|
|
|
|
|
|
|
|
|
{% a = ivar.annotation(MessageType) %}
|
|
|
|
|
|
|
|
|
|
{% if a %}
|
|
|
|
|
{% value = a[0] %}
|
|
|
|
|
{{ name }} = {{ value }}
|
|
|
|
|
{% else %}
|
|
|
|
|
{{ name }}
|
|
|
|
|
{% end %}
|
|
|
|
|
{% end %}
|
2019-11-22 17:31:56 +01:00
|
|
|
|
end
|
2019-11-22 18:14:52 +01:00
|
|
|
|
{% end %}
|
|
|
|
|
|
|
|
|
|
# This is an array of all requests types.
|
|
|
|
|
{% begin %}
|
|
|
|
|
class_getter requests = [
|
|
|
|
|
{% for ivar in @type.subclasses %}
|
|
|
|
|
{% klass = ivar.name %}
|
|
|
|
|
|
|
|
|
|
{{klass}},
|
|
|
|
|
{% end %}
|
|
|
|
|
]
|
|
|
|
|
{% end %}
|
|
|
|
|
|
2019-11-23 01:08:05 +01:00
|
|
|
|
def self.from_ipc(message : IPC::Message) : Request?
|
2019-11-22 18:14:52 +01:00
|
|
|
|
payload = String.new message.payload
|
2020-02-06 10:20:57 +01:00
|
|
|
|
type = Type.new message.utype.to_i
|
2019-11-22 18:14:52 +01:00
|
|
|
|
|
2020-02-26 14:54:14 +01:00
|
|
|
|
begin
|
|
|
|
|
requests.find(&.type.==(type)).try &.from_json(payload)
|
|
|
|
|
rescue e : JSON::ParseException
|
|
|
|
|
raise MalformedRequest.new message.utype.to_i, payload
|
|
|
|
|
end
|
2019-05-29 16:06:11 +02:00
|
|
|
|
end
|
2019-11-22 18:14:52 +01:00
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
module AuthD
|
2020-07-13 14:43:19 +02:00
|
|
|
|
class Client < IPC::Client
|
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 18:14:52 +01:00
|
|
|
|
send Request::GetToken.new login, password
|
2018-11-12 18:51:21 +01:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
response = Response.from_ipc read
|
2018-11-12 18:51:21 +01:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
if response.is_a?(Response::Token)
|
|
|
|
|
response.token
|
2018-11-12 18:51:21 +01:00
|
|
|
|
else
|
|
|
|
|
nil
|
2018-09-22 21:25:03 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-12-19 03:58:00 +01:00
|
|
|
|
def get_user?(login : String, password : String) : AuthD::User::Public?
|
2019-11-22 18:14:52 +01:00
|
|
|
|
send Request::GetUserByCredentials.new login, password
|
2019-02-16 22:06:56 +01:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
response = Response.from_ipc read
|
2019-02-16 22:06:56 +01:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
if response.is_a? Response::User
|
|
|
|
|
response.user
|
2019-02-16 22:06:56 +01:00
|
|
|
|
else
|
|
|
|
|
nil
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
def get_user?(uid_or_login : Int32 | String) : ::AuthD::User::Public?
|
|
|
|
|
send Request::GetUser.new uid_or_login
|
2019-01-07 17:04:20 +01:00
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
response = Response.from_ipc read
|
2019-01-07 17:04:20 +01:00
|
|
|
|
|
2019-12-15 23:38:49 +01:00
|
|
|
|
if response.is_a? Response::User
|
|
|
|
|
response.user
|
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)
|
2020-07-23 19:39:58 +02:00
|
|
|
|
send_now @server_fd, type.value.to_u8, payload
|
2018-12-19 13:54:19 +01:00
|
|
|
|
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-12-15 23:38:49 +01:00
|
|
|
|
user = ::AuthD::User::Public.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.
|
2020-01-22 01:55:57 +01:00
|
|
|
|
def add_user(login : String, password : String,
|
|
|
|
|
email : String?,
|
|
|
|
|
phone : String?,
|
|
|
|
|
profile : JSON::Any?) : ::AuthD::User::Public | Exception
|
|
|
|
|
|
2020-01-22 14:43:58 +01:00
|
|
|
|
send Request::AddUser.new @key, login, password, email, phone, profile
|
2018-12-19 13:54:19 +01:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
response = Response.from_ipc read
|
2018-12-19 13:54:19 +01:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
case response
|
|
|
|
|
when Response::UserAdded
|
|
|
|
|
response.user
|
|
|
|
|
when Response::Error
|
2019-12-15 23:38:49 +01:00
|
|
|
|
raise Exception.new response.reason
|
2018-12-19 13:54:19 +01:00
|
|
|
|
else
|
2019-11-22 22:55:12 +01:00
|
|
|
|
# Should not happen in serialized connections, but…
|
|
|
|
|
# it’ll happen if you run several requests at once.
|
|
|
|
|
Exception.new
|
2018-12-19 13:54:19 +01:00
|
|
|
|
end
|
|
|
|
|
end
|
2019-05-29 16:06:11 +02:00
|
|
|
|
|
2020-01-22 14:43:58 +01:00
|
|
|
|
def validate_user(login : String, activation_key : String) : ::AuthD::User::Public | Exception
|
2020-04-03 16:42:45 +02:00
|
|
|
|
send Request::ValidateUser.new login, activation_key
|
2020-01-22 10:13:59 +01:00
|
|
|
|
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
case response
|
|
|
|
|
when Response::UserValidated
|
|
|
|
|
response.user
|
|
|
|
|
when Response::Error
|
|
|
|
|
raise Exception.new response.reason
|
|
|
|
|
else
|
|
|
|
|
# Should not happen in serialized connections, but…
|
|
|
|
|
# it’ll happen if you run several requests at once.
|
|
|
|
|
Exception.new
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-02-23 20:37:50 +01:00
|
|
|
|
def ask_password_recovery(uid_or_login : String | Int32)
|
|
|
|
|
send Request::AskPasswordRecovery.new uid_or_login
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
send Request::PasswordRecovery.new @key, uid_or_login, renew_key, new_pass
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
case response
|
|
|
|
|
when Response::PasswordRecovered
|
|
|
|
|
when Response::Error
|
|
|
|
|
raise Exception.new response.reason
|
|
|
|
|
else
|
|
|
|
|
Exception.new
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-01-27 13:16:16 +01:00
|
|
|
|
def register(login : String,
|
|
|
|
|
password : String,
|
|
|
|
|
email : String?,
|
|
|
|
|
phone : String?,
|
|
|
|
|
profile : JSON::Any?) : ::AuthD::User::Public?
|
2019-12-15 23:38:49 +01:00
|
|
|
|
|
2020-01-27 13:16:16 +01:00
|
|
|
|
send Request::Register.new login, password, email, phone, profile
|
2019-12-15 23:38:49 +01:00
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
case response
|
|
|
|
|
when Response::UserAdded
|
|
|
|
|
when Response::Error
|
|
|
|
|
raise Exception.new response.reason
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-02-09 15:47:44 +01:00
|
|
|
|
def mod_user(uid_or_login : Int32 | String, password : String? = nil, email : String? = nil, phone : String? = nil, avatar : String? = nil) : Bool | Exception
|
|
|
|
|
request = Request::ModUser.new @key, uid_or_login
|
2019-05-29 16:06:11 +02:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
request.password = password if password
|
2020-02-09 15:47:44 +01:00
|
|
|
|
request.email = email if email
|
|
|
|
|
request.phone = phone if phone
|
2019-11-22 18:14:52 +01:00
|
|
|
|
request.avatar = avatar if avatar
|
2019-05-29 19:45:03 +02:00
|
|
|
|
|
2019-11-22 18:14:52 +01:00
|
|
|
|
send request
|
2019-05-29 16:06:11 +02:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
response = Response.from_ipc read
|
2019-05-29 16:06:11 +02:00
|
|
|
|
|
2019-11-22 22:55:12 +01:00
|
|
|
|
case response
|
|
|
|
|
when Response::UserEdited
|
2019-05-29 16:06:11 +02:00
|
|
|
|
true
|
2019-11-22 22:55:12 +01:00
|
|
|
|
when Response::Error
|
|
|
|
|
Exception.new response.reason
|
2019-05-29 16:06:11 +02:00
|
|
|
|
else
|
2019-11-22 22:55:12 +01:00
|
|
|
|
Exception.new "???"
|
2019-05-29 16:06:11 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
2019-12-15 23:38:49 +01:00
|
|
|
|
|
|
|
|
|
def check_permission(user : ::AuthD::User::Public, service_name : String, resource_name : String) : User::PermissionLevel
|
|
|
|
|
request = Request::CheckPermission.new @key, user.uid, service_name, resource_name
|
|
|
|
|
|
|
|
|
|
send request
|
|
|
|
|
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
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 @key, uid, service, resource, permission
|
|
|
|
|
|
|
|
|
|
send request
|
|
|
|
|
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
case response
|
|
|
|
|
when Response::PermissionSet
|
|
|
|
|
true
|
|
|
|
|
when Response
|
|
|
|
|
raise Exception.new "unexpected response: #{response.type}"
|
|
|
|
|
else
|
|
|
|
|
raise Exception.new "unexpected response"
|
|
|
|
|
end
|
|
|
|
|
end
|
2020-03-23 15:06:54 +01:00
|
|
|
|
|
|
|
|
|
def search_user(user_login : String)
|
|
|
|
|
send Request::SearchUser.new user_login
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
case response
|
|
|
|
|
when Response::MatchingUsers
|
|
|
|
|
response.users
|
|
|
|
|
when Response::Error
|
|
|
|
|
raise Exception.new response.reason
|
|
|
|
|
else
|
|
|
|
|
Exception.new
|
|
|
|
|
end
|
|
|
|
|
end
|
2020-08-10 23:45:44 +02:00
|
|
|
|
|
|
|
|
|
def edit_profile_content(user : Int32 | String, new_values)
|
|
|
|
|
send Request::EditProfileContent.new key, user, new_values
|
|
|
|
|
response = Response.from_ipc read
|
|
|
|
|
|
|
|
|
|
case response
|
|
|
|
|
when Response::User
|
|
|
|
|
response.user
|
|
|
|
|
when Response::Error
|
|
|
|
|
raise Exception.new response.reason
|
|
|
|
|
else
|
|
|
|
|
raise Exception.new "unexpected response"
|
|
|
|
|
end
|
|
|
|
|
end
|
2018-09-22 21:25:03 +02:00
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
2020-07-14 17:48:16 +02:00
|
|
|
|
class IPC::Context
|
|
|
|
|
def send(fd, response : AuthD::Response)
|
|
|
|
|
send fd, response.type.to_u8, response.to_json
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
class IPC::Client
|
|
|
|
|
def send(request : AuthD::Request)
|
|
|
|
|
unless (fd = @server_fd).nil?
|
2020-07-23 19:39:58 +02:00
|
|
|
|
send_now fd, request.type.to_u8, request.to_json
|
2020-07-14 17:48:16 +02:00
|
|
|
|
else
|
|
|
|
|
raise "Client not connected to the server"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|