<commit_before>package ufront.auth.model;

#if client 
	import promhx.Promise;
#end
import ufront.db.Object;
import ufront.db.ManyToMany;
import sys.db.Types;
using Lambda;

@:table("auth_user")
@:index(username,unique)
class User extends Object implements ufront.auth.UFAuthUser
{
	public var username:SString<40>;
	public var salt:SString<32>;
	public var password:SString<64>;
	public var forcePasswordChange:Bool;

	public var userPermissions:HasMany<Permission>;
	public var groups:ManyToMany<User, Group>;
	@:skip public var userID(get,null):String;

	public function new(u:String, p:String)
	{
		super();
		#if server 
			this.username = u;
			this.setPassword( p );
			this.forcePasswordChange = false;
		#end 
	}

	/** Generate a new salt and password.  You will need to call save() yourself */
	public function setPassword(password:String)
	{
		#if server 
			this.salt = Random.string(32);
			this.password = generatePasswordHash(password, salt);
		#end
	}

	/** Check permissions.  if (myUser.can(DriveCar) or if (myUser.can([DriveCar,BorrowParentsCar])) { ... } */
	public function can( ?permission:EnumValue, ?permissions:Iterable<EnumValue> )
	{
		loadUserPermissions();
		if (allUserPermissions==null) return false; // Permissions not loaded yet...
		if (permission!=null) if ( !checkPermission(permission) ) return false;
		if (permissions!=null) for ( p in permissions ) if ( !checkPermission(p) ) return false;
		return true;
	}

	function get_userID() {
		return username;
	}

	function checkPermission( p:EnumValue ) 
	{
		return allUserPermissions.has( Permission.getPermissionID(p) );
	}

	@:skip var allUserPermissions:List<String>;
	function loadUserPermissions()
	{
		if (allUserPermissions == null)
		{
			allUserPermissions = new List();
			#if (server || ufront_clientds)
				for ( g in groups )
					for ( p in g.permissions )
						allUserPermissions.add( p.permission );
				for ( p in userPermissions )
					allUserPermissions.add( p.permission );<commit_msg>On server, get permissions for user in fewer SQL queries<commit_after>package ufront.auth.model;

#if client 
	import promhx.Promise;
#end
import ufront.db.Object;
import ufront.db.ManyToMany;
import sys.db.Types;
using Lambda;

@:table("auth_user")
@:index(username,unique)
class User extends Object implements ufront.auth.UFAuthUser
{
	public var username:SString<40>;
	public var salt:SString<32>;
	public var password:<PASSWORD><64>;
	public var forcePasswordChange:Bool;

	public var userPermissions:HasMany<Permission>;
	public var groups:ManyToMany<User, Group>;
	@:skip public var userID(get,null):String;

	public function new(u:String, p:String)
	{
		super();
		#if server 
			this.username = u;
			this.setPassword( p );
			this.forcePasswordChange = false;
		#end 
	}

	/** Generate a new salt and password.  You will need to call save() yourself */
	public function setPassword(password:String)
	{
		#if server 
			this.salt = Random.string(32);
			this.password = generatePasswordHash(password, salt);
		#end
	}

	/** Check permissions.  if (myUser.can(DriveCar) or if (myUser.can([DriveCar,BorrowParentsCar])) { ... } */
	public function can( ?permission:EnumValue, ?permissions:Iterable<EnumValue> )
	{
		loadUserPermissions();
		if (allUserPermissions==null) return false; // Permissions not loaded yet...
		if (permission!=null) if ( !checkPermission(permission) ) return false;
		if (permissions!=null) for ( p in permissions ) if ( !checkPermission(p) ) return false;
		return true;
	}

	function get_userID() {
		return username;
	}

	function checkPermission( p:EnumValue ) 
	{
		return allUserPermissions.has( Permission.getPermissionID(p) );
	}

	@:skip var allUserPermissions:List<String>;
	function loadUserPermissions()
	{
		if (allUserPermissions == null)
		{
			#if server
				var groupIDs = [ for (g in groups) g.id ];
				var permissions = Permission.manager.search( $userID==this.id || $groupID in groupIDs );
				allUserPermissions = permissions.map( function(p) return p.permission );
				trace( allUserPermissions );
			#else
				allUserPermissions = new List();
				#if ufront_clientds
					for ( g in groups )
						for ( p in g.permissions )
							allUserPermissions.add( p.permission );
					for ( p in userPermissions )
						allUserPermissions.add( p.permission );
				#end
{'fraction_non_alphanumeric': 0.11910842814023682, 'fraction_numerical': 0.0037148827490132343, 'mean_word_length': 4.3250927070457355, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3284168', 'n_tokens_mistral': 1506, 'n_tokens_neox': 1372, 'n_words': 359}