diff --git a/include/class-Mailbox.php b/include/class-Mailbox.php index 6c77b9d..8e9a171 100644 --- a/include/class-Mailbox.php +++ b/include/class-Mailbox.php @@ -1,99 +1,108 @@ . /** * A mailbox */ class Mailbox extends Domain { const T = 'mailbox'; public function __construct() { $this->booleans( 'mailbox_receive' ); } + /** + * Get the mailbox username + * + * @return string + */ + public function getMailboxUsername() { + return $this->get( 'mailbox_username' ); + } + /** * Get the mailbox address * * @return string E-mail */ public function getMailboxAddress() { return sprintf( "%s@%s", $this->get( 'mailbox_username' ), $this->get( 'domain_name' ) ); } /** * Get the mailbox permalink * * @return string */ public function getMailboxPermalink( $absolute = false ) { return Mailbox::permalink( $this->get( 'domain_name' ), $this->get( 'mailbox_username' ) ); } /** * Update this mailbox password * * @param $password string * @return string */ public function updateMailboxPassword( $password = null ) { if( ! $password ) { $password = generate_password(); } $enc_password = Mailbox::encryptPassword( $password ); query_update( 'mailbox', [ new DBCol( 'mailbox_password', $enc_password, 's' ), ], sprintf( "domain_ID = %d AND mailbox_username = '%s'", $this->getDomainID(), esc_sql( $this->get( 'mailbox_username' ) ) ) ); return $password; } /** * Get the mailbox permalink * * @param $domain string * @param $mailbox string * @param $absolute boolean * @return string */ public static function permalink( $domain, $mailbox = null, $absolute = false ) { $part = site_page( 'mailbox.php', $absolute ) . _ . $domain; if( $mailbox ) { $part .= _ . $mailbox; } return $part; } /** * Encrypt a password * * TODO: do not hardcode to my Dovecot configuration */ public static function encryptPassword( $password ) { $salt = bin2hex( openssl_random_pseudo_bytes( 3 ) ); return '{SHA512-CRYPT}' . crypt( $password, "$6$$salt" ); } } diff --git a/include/class-MailboxAPI.php b/include/class-MailboxAPI.php index fdc94c8..822fa2a 100644 --- a/include/class-MailboxAPI.php +++ b/include/class-MailboxAPI.php @@ -1,54 +1,64 @@ . /** * Mailbox API */ class MailboxAPI extends DomainAPI { public function __construct() { Query::__construct(); $this->from( Mailbox::T ); $this->defaultClass( 'Mailbox' ); } + /** + * Where the Mailbox is Active (or not) + * + * @param boolean $active If you want the active, or the inactive + * @return self + */ + public function whereMailboxIsActive( $active = true ) { + return $this->wheerInt( 'mailbox_active', $active ); + } + /** * Join mailboxes and domain (once) * * @return self */ public function joinMailboxDomain() { if( empty( $this->joinedMailboxDomain ) ) { $this->from( 'domain' ); $this->equals( 'domain.domain_ID', 'mailbox.domain_ID' ); $this->joinedMailboxDomain = true; } return $this; } /** * Check if I can edit this mailbox * * Actually it just checks if you can edit the whole domain. * * @return boolean */ public function whereMailboxIsEditable() { return $this->whereDomainIsEditable(); } } diff --git a/include/class-User.php b/include/class-User.php new file mode 100644 index 0000000..ebce5c4 --- /dev/null +++ b/include/class-User.php @@ -0,0 +1,162 @@ +. + +trait UserTrait { + + /** + * Normalize a User object + */ + protected function normalizeUser() { + $this->integers( 'user_ID' ); + } + + /** + * Get the user ID + * + * @return int + */ + public function getUserID() { + return $this->get( 'user_ID' ); + } + + /** + * Get the user first name + * + * @return string + */ + public function getUserName() { + return $this->get( 'user_name' ); + } + + /** + * Get the user surname + * + * @return string + */ + public function getUserSurname() { + return $this->get( 'user_surname' ); + } + + /** + * Get the user UID + * + * @return string + */ + public function getUserUID() { + return $this->get( 'user_uid' ); + } + + /** + * Get the user E-mail + * + * @return string + */ + public function getUserEmail() { + return $this->get( 'user_email' ); + } + + /** + * Get the role of this user + * + * @return string + */ + public function getUserRole() { + return $this->get( 'user_role' ); + } + + /** + * Get the human name of the user role + * + * @return string + */ + public function getUserRoleLabel() { + $roles = User::roles(); + $role = $this->getUserRole(); + return $roles[ $role ]; + } + + /** + * Check if this user is me + * + * @return boolean + */ + public function isUserMyself() { + $id = $this->getUserID(); + return is_logged() && get_user()->getUserID() === $id; + } + + /** + * Check if I can edit this user + * + * @return boolean + */ + public function isUserEditable() { + return $this->isUserMyself() || has_permission( 'edit-user-all' ); + } + + /** + * Get the domain edit URl + * + * @param boolean $absolute True for an absolute URL + * @return string + */ + public function getUserPermalink( $absolute = false ) { + return User::permalink( $this->getUserUID(), $absolute ); + } +} + +/** + * A mailbox + */ +class User extends Sessionuser { + + use UserTrait; + + /** + * Constructor + */ + public function __construct() { + $this->normalizeUser(); + } + + /** + * Get the known user roles + * + * @return array + */ + public static function roles() { + return [ + 'user' => __( "User" ), + 'admin' => __( "Admin" ), + ]; + } + + /** + * Get the User permalink + * + * @param string $user User UID + * @param boolean $absolute + * @return string + */ + public static function permalink( $user = null, $absolute = false ) { + $part = site_page( 'user.php', $absolute ); + if( $user ) { + $part .= _ . $user; + } + return $part; + } +} diff --git a/include/class-UserAPI.php b/include/class-UserAPI.php index 1195e8c..2aa663a 100644 --- a/include/class-UserAPI.php +++ b/include/class-UserAPI.php @@ -1,93 +1,103 @@ . /** * User users API */ class UserAPI extends DomainAPI { /** * Column name of the User ID */ const USER_ID = 'user.user_ID'; /** * Constructor */ public function __construct() { Query::__construct(); $this->from( User::T ); - $this->defaultClass( 'User' ); + $this->defaultClass( User::class ); } /** * Filter to a certain User UID * * @param string $uid User UID * @return self */ public function whereUserUID( $uid ) { return $this->whereStr( 'user_uid', $uid ); } + /** + * Filter to a certain User E-mail + * + * @param string $email User E-mail + * @return self + */ + public function whereUserEmail( $email ) { + return $this->whereStr( 'user_email', $email ); + } + /** * Filter to a certain User ID * * @param string $uid User ID * @return self */ public function whereUserID( $id ) { return $this->whereInt( static::USER_ID, $id ); } /** * Filter to myself * * @return self */ public function whereUserIsMe() { - $id = get_user()->getSessionuserID(); + $id = get_user()->getUserID(); return $this->whereUserID( $id ); } /** * WHere the User(s) is editable * * @return Query */ public function whereUserIsEditable() { // if I can't see everyone, just see myself - if( !has_permission( 'edit-all-users' ) ) { + if( !has_permission( 'edit-user-all' ) ) { $this->whereUserIsMe(); } return $this; } /** * Limit to a specific User * * @param object $user User * @return self */ public function whereUser( $user ) { - $id = $user->whereSessionuserID(); + $id = $user->getSessionuserID(); return $this->whereUserID( $id ); } } diff --git a/include/class-UserPager.php b/include/class-UserPager.php index 7853551..3a33eff 100644 --- a/include/class-UserPager.php +++ b/include/class-UserPager.php @@ -1,61 +1,79 @@ . /** * User users API */ class UserPager extends QueryPager { /** * Constructor * * @param $data array */ public function __construct( $data = [] ) { parent::__construct(); if( isset( $data['uid'] ) ) { $data['uid'] = luser_input( $data['uid'], 32 ); $this->setArg( 'uid', $data['uid'] ); } + + if( isset( $data['email'] ) ) { + $data['email'] = luser_input( $data['email'], 32 ); + $this->setArg( 'email', $data['email'] ); + } } /** * Create a Query for User(s) * * @return Query */ public function createQuery() { $query = new UserAPI(); $query->whereUserIsEditable(); + // search by login + $uid = $this->getArg( 'uid' ); + $email = $this->getArg( 'email' ); + + if( $uid ) { + $query->whereUserUID( $uid ); + } + + if( $email ) { + $query->whereUserEmail( $email ); + } + return $query; } /** * Eventually apply an order * * @override */ public function applyOrder( & $query, $order_by, $direction ) { + $query->orderBy( 'user_uid' ); } } diff --git a/load-post.php b/load-post.php index 3aa7734..ad0be38 100644 --- a/load-post.php +++ b/load-post.php @@ -1,86 +1,101 @@ . // include path define_default( 'INCLUDE_PATH', ABSPATH . __ . 'include' ); // template path define_default( 'TEMPLATE_PATH', ABSPATH . __ . 'template' ); // autoload classes from the /include directory spl_autoload_register( function( $name ) { $path = INCLUDE_PATH . __ . "class-$name.php"; if( is_file( $path ) ) { require $path; } } ); +// override default user class +define( 'SESSIONUSER_CLASS', 'User' ); + // load common functions require INCLUDE_PATH . __ . 'functions.php'; // jquery URL // provided by the libjs-jquery package as default define_default( 'JQUERY_URL', '/javascript/jquery/jquery.min.js' ); // Bootstrap CSS/JavaScript files without trailing slash // provided by the libjs-bootstrap package as default define_default( 'BOOTSTRAP_DIR_URL', '/javascript/bootstrap' ); // path to the Net SMTP class // provided by the php-net-smtp package as default define_default( 'NET_SMTP', '/usr/share/php/Net/SMTP.php' ); // register JavaScript/CSS files register_js( 'jquery', JQUERY_URL ); register_js( 'bootstrap', BOOTSTRAP_DIR_URL . '/js/bootstrap.min.js' ); register_css( 'bootstrap', BOOTSTRAP_DIR_URL . '/css/bootstrap.min.css' ); register_css( 'custom-css', ROOT . '/content/style.css' ); // GNU Gettext i18n define( 'GETTEXT_DOMAIN', 'reyboz-hosting-panel' ); define( 'GETTEXT_DIRECTORY', 'l10n' ); define( 'GETTEXT_DEFAULT_ENCODE', CHARSET ); // UTF-8 // common strings define_default( 'SITE_NAME', "Boz Libre Hosting Panel" ); define_default( 'CONTACT_EMAIL', 'support@' . DOMAIN ); define_default( 'REPO_URL', 'https://github.com/valerio-bozzolan/boz-libre-hosting-panel' ); // limit session duration to 5 minutes (60s * 100m) define_default( 'SESSION_DURATION', 6000 ); +/** + * Mailbox base path + * + * Used by CLI scripts to calculate the current quotas. + * + * The mailboxes should have paths like: + * MAILBOX_BASE_PATH/domain_name/user_name/ + */ +define_default( 'MAILBOX_BASE_PATH', '/home/vmail' ); + // register web pages add_menu_entries( [ - new MenuEntry( 'index', '/', __( "Dashboard" ) ), - new MenuEntry( 'login', 'login.php', __( "Login" ) ), - new MenuEntry( 'profile', 'profile.php', __( "Profile" ) ), - new MenuEntry( 'logout', 'logout.php', __( "Logout" ) ), - new MenuEntry( 'password-reset', 'password-reset.php', __( "Password reset" ) ), + new MenuEntry( 'index', '/', __( "Dashboard" ), null, 'backend' ), + new MenuEntry( 'login', 'login.php', __( "Login" ) ), + new MenuEntry( 'profile', 'profile.php', __( "Profile" ) ), + new MenuEntry( 'logout', 'logout.php', __( "Logout" ), null, 'read' ), + new MenuEntry( 'user-list', 'user-list.php', __( "Users" ), null, 'edit-user-all' ), + new MenuEntry( 'password-reset', 'password-reset.php', __( "Password reset" ) ), ] ); -// permissions +// permissions of a normal user register_permissions( 'user', [ 'read', 'backend', ] ); +// permissions of an admin inherit_permissions( 'admin', 'user', [ 'edit-user-all', 'edit-email-all', 'edit-domain-all', 'edit-ftp-all', ] ); diff --git a/template/user.php b/template/user.php new file mode 100644 index 0000000..3df0bce --- /dev/null +++ b/template/user.php @@ -0,0 +1,60 @@ +. + +/* + * This is the template for an User + * + * Called from: + * user.php + * + * Available variables: + * $user object|null + * $new_password string|null + */ + +// unuseful when load directly +defined( 'BOZ_PHP' ) or die; +?> + +
+ + += esc_html( __( "The new password is:" ) ) ?>
+ /> + +
domain_active ): ?>
= HTML::a(
$domain->getDomainPermalink(),
$domain->domain_name
) ?>
= esc_html( $domain->domain_name ) ?>
| = esc_html( __( "Login" ) ) ?> | += esc_html( __( "Surname" ) ) ?> | += esc_html( __( "Name" ) ) ?> | += esc_html( __( "Role" ) ) ?> | +
|---|---|---|---|
| = HTML::a( + $user->getUserPermalink(), + $user->getUserUID() + ) ?> | += esc_html( $user->getUserSurname() ) ?> | += esc_html( $user->getUserName() ) ?> | += esc_html( $user->getUserRoleLabel() ) ?> | +