Merge pull request #10 from Lukc/master

WIP ModUserRequest
ipc07
Philippe Pittoli 2019-05-29 22:03:15 +02:00 committed by GitHub
commit 448f7a3796
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 12 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)