using InvercargillSql.Orm; using Spry.Authorisation; using Invercargill.Expressions; using Invercargill; using Invercargill.DataStructures; using Inversion; namespace Spry.Authentication { public class UserService : Object { private OrmSession db = inject(); private AuthorisationService authorisation_service = inject(); public async AuthorisationToken? authenticate_user(string username, string password) throws Error { print(expr("username == $0", new NativeElement(username)).to_expression_string()); var user = yield db.query() .where(expr("username == $0", new NativeElement(username)).to_expression_string()) .first_async(); if(!Sodium.PasswordHashing.check(user.password_hash, password)){ return null; } return authorisation_service.authorise_identity(user); } public async UserEntity register_user(string username, string email, string forename, string surname, DateTime date_of_birth, string password, bool enabled = true) throws Error { var user = new UserEntity() { username = username, email = email, forename = forename, surname = surname, password_hash = Sodium.PasswordHashing.hash(password), date_of_birth = date_of_birth, created = new DateTime.now_utc(), modified = new DateTime.now_utc(), enabled = enabled, }; yield yield db.insert_async(user); return user; } public async void set_password(int64 user_id, string password) throws Error { var user = yield db.query() .where(expr("id == $0", new NativeElement(user_id)).to_expression_string()) .first_async(); user.password_hash = Sodium.PasswordHashing.hash(password); user.modified = new DateTime.now_utc(); yield yield db.update_async(user); } public async UserEntity alter_user(int64 user_id, string username, string email, string forename, string surname, DateTime date_of_birth, bool enabled) throws Error { var user = yield db.query() .where(expr("id == $0", new NativeElement(user_id)).to_expression_string()) .first_async(); user.username = username; user.email = email; user.forename = forename; user.surname = surname; user.date_of_birth = date_of_birth; user.modified = new DateTime.now_utc(); user.enabled = enabled; yield db.update_async(user); return user; } public async void set_user_enabled(int64 user_id, bool enabled) throws Error { var user = yield db.query() .where(expr("id == $0", new NativeElement(user_id)).to_expression_string()) .first_async(); user.modified = new DateTime.now_utc(); user.enabled = enabled; yield db.update_async(user); } public async ImmutableLot list_users(int64 offset = 0, int64 limit = 100) throws Error { return yield db.query() .offset(offset) .limit(limit) .materialise_async(); } public async void delete_user(int64 user_id) throws Error { var user = yield db.query() .where(expr("id == $0", new NativeElement(user_id)).to_expression_string()) .first_async(); db.delete(user); } public async void set_user_permission(int64 user_id, string permission) throws Error { var user_permission = new UserPermissionEntity() { user_id = user_id, permission = permission }; yield db.insert_async(user_permission); } public async void clear_user_permissions(int64 user_id) throws Error { var permissions = yield db.query() .where(expr("user_id == $0", new NativeElement(user_id)).to_expression_string()) .materialise_async(); foreach (var permission in permissions) { db.delete(permission); } } public async ImmutableLot get_user_permissions(int64 user_id) throws Error { var permissions = yield db.query() .where(expr("user_id == $0", new NativeElement(user_id)).to_expression_string()) .materialise_async(); var result = new Vector(); foreach (var permission in permissions) { result.add(permission.permission); } return result.to_immutable_buffer(); } } }