commit
448f7a3796
33
src/authd.cr
33
src/authd.cr
|
@ -12,6 +12,7 @@ module AuthD
|
||||||
AddUser
|
AddUser
|
||||||
GetUser
|
GetUser
|
||||||
GetUserByCredentials
|
GetUserByCredentials
|
||||||
|
ModUser # Edit user attributes.
|
||||||
end
|
end
|
||||||
|
|
||||||
enum ResponseTypes
|
enum ResponseTypes
|
||||||
|
@ -54,6 +55,14 @@ module AuthD
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class ModUserRequest
|
||||||
|
JSON.mapping({
|
||||||
|
uid: Int32,
|
||||||
|
password: String?,
|
||||||
|
avatar: String?
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
class Client < IPC::Client
|
class Client < IPC::Client
|
||||||
property key : String
|
property key : String
|
||||||
|
|
||||||
|
@ -134,6 +143,30 @@ module AuthD
|
||||||
Exception.new response.payload
|
Exception.new response.payload
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mod_user(uid : Int32, password : String? = nil, avatar : String? = nil) : Bool | Exception
|
||||||
|
payload = Hash(String, String|Int32).new
|
||||||
|
payload["uid"] = uid
|
||||||
|
|
||||||
|
password.try do |password|
|
||||||
|
payload["password"] = password
|
||||||
|
end
|
||||||
|
|
||||||
|
avatar.try do |avatar|
|
||||||
|
payload["avatar"] = avatar
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
17
src/main.cr
17
src/main.cr
|
@ -121,6 +121,23 @@ IPC::Service.new "auth" do |event|
|
||||||
else
|
else
|
||||||
client.send ResponseTypes::UserNotFound, ""
|
client.send ResponseTypes::UserNotFound, ""
|
||||||
end
|
end
|
||||||
|
when RequestTypes::ModUser
|
||||||
|
begin
|
||||||
|
request = ModUserRequest.from_json payload
|
||||||
|
rescue e
|
||||||
|
client.send ResponseTypes::MalformedRequest, e.message || ""
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
password_hash = request.password.try do |s|
|
||||||
|
Passwd.hash_password s
|
||||||
|
end
|
||||||
|
|
||||||
|
avatar = request.avatar
|
||||||
|
|
||||||
|
passwd.mod_user request.uid, password_hash: password_hash, avatar: avatar
|
||||||
|
|
||||||
|
client.send ResponseTypes::Ok, ""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require "csv"
|
require "csv"
|
||||||
require "uuid"
|
require "uuid"
|
||||||
|
require "base64"
|
||||||
|
|
||||||
require "./user.cr"
|
require "./user.cr"
|
||||||
require "./group.cr"
|
require "./group.cr"
|
||||||
|
@ -69,9 +70,7 @@ class Passwd
|
||||||
##
|
##
|
||||||
# Will fail if the user is found but the password is invalid.
|
# Will fail if the user is found but the password is invalid.
|
||||||
def get_user(login : String, password : String) : AuthD::User?
|
def get_user(login : String, password : String) : AuthD::User?
|
||||||
digest = OpenSSL::Digest.new("sha256")
|
hash = Passwd.hash_password password
|
||||||
digest << password
|
|
||||||
hash = digest.hexdigest
|
|
||||||
|
|
||||||
each_user do |user|
|
each_user do |user|
|
||||||
if user.login == login
|
if user.login == login
|
||||||
|
@ -138,6 +137,12 @@ class Passwd
|
||||||
gid
|
gid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.hash_password(password)
|
||||||
|
digest = OpenSSL::Digest.new("sha256")
|
||||||
|
digest << password
|
||||||
|
digest.hexdigest
|
||||||
|
end
|
||||||
|
|
||||||
def add_user(login, password = nil, uid = nil, gid = nil, home = "/", shell = "/bin/nologin")
|
def add_user(login, password = nil, uid = nil, gid = nil, home = "/", shell = "/bin/nologin")
|
||||||
# FIXME: If user already exists, exception? Replacement?
|
# FIXME: If user already exists, exception? Replacement?
|
||||||
|
|
||||||
|
@ -146,9 +151,7 @@ class Passwd
|
||||||
gid = get_free_gid if gid.nil?
|
gid = get_free_gid if gid.nil?
|
||||||
|
|
||||||
password_hash = if password
|
password_hash = if password
|
||||||
digest = OpenSSL::Digest.new("sha256")
|
Passwd.hash_password password
|
||||||
digest << password
|
|
||||||
digest.hexdigest
|
|
||||||
else
|
else
|
||||||
"x"
|
"x"
|
||||||
end
|
end
|
||||||
|
@ -171,6 +174,29 @@ class Passwd
|
||||||
|
|
||||||
File.write(@group, group.to_csv + "\n", mode: "a")
|
File.write(@group, group.to_csv + "\n", mode: "a")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# FIXME: Edit other important fields.
|
||||||
|
def mod_user(uid, password_hash : String? = nil, avatar : String? = nil)
|
||||||
|
new_passwd = passwd_as_array.map do |line|
|
||||||
|
user = AuthD::User.new line
|
||||||
|
|
||||||
|
if uid == user.uid
|
||||||
|
password_hash.try do |hash|
|
||||||
|
user.password_hash = hash
|
||||||
|
end
|
||||||
|
|
||||||
|
avatar.try do |avatar|
|
||||||
|
user.avatar = avatar
|
||||||
|
end
|
||||||
|
|
||||||
|
user.to_csv
|
||||||
|
else
|
||||||
|
line.join(':') + "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
File.write @passwd, new_passwd.join
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class AuthD::Group
|
class AuthD::Group
|
||||||
|
@ -201,7 +227,15 @@ class AuthD::User
|
||||||
@office_phone_number = gecos[2]?
|
@office_phone_number = gecos[2]?
|
||||||
@home_phone_number = gecos[3]?
|
@home_phone_number = gecos[3]?
|
||||||
@other_contact = gecos[4]?
|
@other_contact = gecos[4]?
|
||||||
@avatar = gecos[5]? # CAUTION: NON-STANDARD EXTENSION
|
|
||||||
|
# CAUTION: NON-STANDARD EXTENSION
|
||||||
|
@avatar = gecos[5]?.try do |x|
|
||||||
|
if x != ""
|
||||||
|
Base64.decode_string x
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# FIXME: What about those two fields? Keep them, remove them?
|
# FIXME: What about those two fields? Keep them, remove them?
|
||||||
|
@ -214,7 +248,7 @@ class AuthD::User
|
||||||
end
|
end
|
||||||
|
|
||||||
def gecos
|
def gecos
|
||||||
unless @location || @office_phone_number || @home_phone_number || @other_contact
|
unless @location || @office_phone_number || @home_phone_number || @other_contact || @avatar
|
||||||
if @full_name
|
if @full_name
|
||||||
return @full_name
|
return @full_name
|
||||||
else
|
else
|
||||||
|
@ -222,7 +256,7 @@ class AuthD::User
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
[@full_name || "", @location || "", @office_phone_number || "", @home_phone_number || "", @other_contact || ""].join ","
|
[@full_name || "", @location || "", @office_phone_number || "", @home_phone_number || "", @other_contact || "", Base64.strict_encode(@avatar || "")].join ","
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
|
||||||
|
require "json"
|
||||||
|
|
||||||
class AuthD::User
|
class AuthD::User
|
||||||
getter login : String
|
|
||||||
getter password_hash : String
|
|
||||||
getter uid : Int32
|
getter uid : Int32
|
||||||
getter gid : Int32
|
getter gid : Int32
|
||||||
|
getter login : String
|
||||||
|
getter password_hash : String
|
||||||
getter home : String = "/"
|
getter home : String = "/"
|
||||||
getter shell : String = "/bin/nologin"
|
getter shell : String = "/bin/nologin"
|
||||||
getter groups = Array(String).new
|
getter groups = Array(String).new
|
||||||
|
@ -25,7 +27,8 @@ class AuthD::User
|
||||||
full_name: String?,
|
full_name: String?,
|
||||||
office_phone_number: String?,
|
office_phone_number: String?,
|
||||||
home_phone_number: String?,
|
home_phone_number: String?,
|
||||||
other_contact: String?
|
other_contact: String?,
|
||||||
|
avatar: String?
|
||||||
})
|
})
|
||||||
|
|
||||||
def initialize(@login, @password_hash, @uid, @gid, @home, @shell)
|
def initialize(@login, @password_hash, @uid, @gid, @home, @shell)
|
||||||
|
|
Loading…
Reference in New Issue