diff --git a/include/class-Breadcrumb.php b/include/class-Breadcrumb.php index 5105877..8731ae5 100644 --- a/include/class-Breadcrumb.php +++ b/include/class-Breadcrumb.php @@ -1,79 +1,79 @@ . /** * Handle a breadcrumb with the related microdata * * @url https://schema.org/BreadcrumbList * @url https://developers.google.com/search/docs/data-types/breadcrumb */ class Breadcrumb { /** * Spawn the breadcrumb * * @param $uid string|null Starting menu uid * @param $title string|null Starting title * @param $parent_uid string|null Parent menu uid */ public static function spawn( $breadcrumbs ) { ?>
url ? $entry->getSitePage() : null; + $url = $entry->url ? $entry->getURL() : null; return self::link( $i, $url, $entry->name ); } /** * Get a link with microdata * * @param int $i * @param string $url * @param string $title * @return string */ public static function link( $i, $url, $title ) { $s = '= __( "To enter in your website with this FTP user you can copy this address into your file manager (then it should ask for the related password):" ) ?>
+ if( isset( $data['uid'] ) ) { + $data['uid'] = luser_input( $data['uid'], 32 ); + $this->setArg( 'uid', $data['uid'] ); + } + } -
- ftp://getFTPLogin() );
- echo '@';
- _esc_html( $domain->getDomainName() );
- ?>
-
+ /**
+ * Create a Query for User(s)
+ *
+ * @return Query
+ */
+ public function createQuery() {
+ $query = new UserAPI();
+
+ $query->whereUserIsEditable();
+
+ return $query;
+ }
+
+
+ /**
+ * Eventually apply an order
+ *
+ * @override
+ */
+ public function applyOrder( & $query, $order_by, $direction ) {
+
+
+ }
+
+}
diff --git a/include/functions.php b/include/functions.php
index ffb00a4..c00a77d 100644
--- a/include/functions.php
+++ b/include/functions.php
@@ -1,195 +1,201 @@
.
/**
* Require a certain page from the template directory
*
* @param $name string page name (to be sanitized)
* @param $args mixed arguments to be passed to the page scope
*/
function template( $template_name, $template_args = [] ) {
extract( $template_args, EXTR_SKIP );
return require TEMPLATE_PATH . __ . "$template_name.php";
}
/**
* Get the returned text from a template
*
* @param $name string page name (to be sanitized)
* @param $args mixed arguments to be passed to the page scope
* @see template()
* @return string
*/
function template_content( $name, $args = [] ) {
ob_start();
template( $name, $args );
$text = ob_get_contents();
ob_end_clean();
return $text;
}
/**
* Print an e-mail (safe for bots)
*
* @param $email string
*/
function email_blur( $email ) {
$dot = strip_tags( __( " dot " ) );
$at = strip_tags( __( " at " ) );
$email = esc_html( $email );
echo str_replace( [ '.', '@' ], [ $dot, $at ], $email );
}
/**
* Send an e-mail to someone
*
* @param $subject string E-mail subject
* @param $message string E-mail message
* @param $to string E-mail recipient (from current logged-in user as default)
*/
function send_email( $subject, $message, $to = false ) {
if( ! $to ) {
if( ! is_logged() ) {
die( "can't retrieve e-mail address from anon user" );
}
$to = get_user( 'user_email' );
}
return SMTPMail::instance()
->to( $to )
->message( $subject, $message )
->disconnect();
}
/**
* Require a certain permission
*
* @param $permission string An internal permission like 'edit-all-user'
* @param $redirect boolean Enable or disable the redirect
*/
function require_permission( $permission, $redirect = true ) {
if( ! has_permission( $permission ) ) {
- if( is_logged() ) {
- Header::spawn( [
- 'title' => __( "Permission denied" ),
+ require_more_privileges( $redirect );
+ }
+}
+
+/**
+ * Require more privileges then actual ones
+ */
+function require_more_privileges( $redirect = true ) {
+ if( is_logged() ) {
+ Header::spawn( [
+ 'title' => __( "Permission denied" ),
+ ] );
+ Footer::spawn();
+ exit;
+ } else {
+ $login = menu_entry( 'login' );
+ $url = $login->getAbsoluteURL();
+ if( $redirect && isset( $_SERVER[ 'REQUEST_URI' ] ) ) {
+ $url = http_build_get_query( $url, [
+ 'redirect' => $_SERVER[ 'REQUEST_URI' ],
] );
- Footer::spawn();
- exit;
- } else {
- $login = menu_entry( 'login' );
- $url = $login->getSitePage( URL );
- if( $redirect && isset( $_SERVER[ 'REQUEST_URI' ] ) ) {
- $url = http_build_get_query( $url, [
- 'redirect' => $_SERVER[ 'REQUEST_URI' ],
- ] );
- }
- http_redirect( $url, 307 );
}
+ http_redirect( $url, 307 );
}
}
-
/**
* Get URL parts from the PATH_INFO
*
* It spawn a "bad request" page if something goes wrong.
*
* @param $max int If $min is specified, this is the maximum number of parameters. When unspecified, this is the exact number of parameters.
* @param $min int Mininum number of parameters.
* @return array
* @see https://httpd.apache.org/docs/2.4/mod/core.html#acceptpathinfo
*/
function url_parts( $max, $min = false ) {
if( $min === false ) {
$min = $max;
}
// split the PATH_INFO parts
$parts = explode( _, $_SERVER[ 'PATH_INFO' ] );
array_shift( $parts );
// eventually spawn the "bad request"
$n = count( $parts );
if( $n > $max || $n < $min ) {
BadRequest::spawn( __( "unexpected URL" ) );
}
// eventually fill expected fields
for( $i = $n; $i < $max; $i++ ) {
$parts[] = null;
}
return $parts;
}
/**
* Link to an existing page from the menu
*
* @param $uid string E.g. 'index'
* @param $args mixed Arguments
*/
function the_menu_link( $uid, $args = [] ) {
$page = menu_entry( $uid );
- the_link( $page->getSitePage(), $page->name, $args );
+ the_link( $page->getURL(), $page->name, $args );
}
/**
* Link to a whatever page
*
* P.S. link() is a reserved function
*
* @param $url string
* @param $title string
* @param $args mixed Arguments
*/
function the_link( $url, $title, $args = [] ) {
template( 'link', [
'title' => $title,
'url' => $url,
'args' => $args,
] );
}
/**
* Generate a password
*
* @param $bytes int
*/
function generate_password( $bytes = 8 ) {
return rtrim( base64_encode( bin2hex( openssl_random_pseudo_bytes( $bytes ) ) ), '=' );
}
/**
* Validate a mailbox username
*
* @param $mailbox string
* @return bool
*/
function validate_mailbox_username( $mailbox ) {
return 1 === preg_match( '/^[a-z][a-z0-9-_.]+$/', $mailbox );
}
/**
* A certain value must be an e-mail
*
* @param $email string
* @return string filtered e-mail
*/
function require_email( $email ) {
$email = luser_input( $email, 128 );
if( filter_var( $email, FILTER_VALIDATE_EMAIL ) === false ) {
BadRequest::spawn( __( "fail e-mail validation" ) );
}
return $email;
}
diff --git a/template/ftp-access.php b/template/ftp-access.php
index be16693..79fe536 100644
--- a/template/ftp-access.php
+++ b/template/ftp-access.php
@@ -1,41 +1,41 @@
.
/*
* This is the template for FTP instructions
*
* Called from:
* ftp.php
*
* Available variables:
* $domain Domain object
* $ftp FTP object
*/
// unuseful when load directly
defined( 'BOZ_PHP' ) or die;
?>
- = __( "To enter in your website with this FTP user you can copy this address into your file manager (then it should ask for the related password):" ) ?>
+= esc_html( __( "To enter in your website with this FTP user you can copy this address into your file manager (then it should ask for the related password):" ) ) ?>
- ftp://getFTPLogin() );
- echo '@';
- _esc_html( $domain->getDomainName() );
+ ftp://=
+ esc_html( $ftp->getFTPLogin() ) .
+ '@' .
+ esc_html( $domain->getDomainName() );
?>
diff --git a/template/header.php b/template/header.php
index 28b88a8..dc7aaf0 100644
--- a/template/header.php
+++ b/template/header.php
@@ -1,73 +1,73 @@
.
/*
* This is the template for the website header
*
* Called from:
* include/class-Header.php
*
* Available variables:
* $args array
*/
// unuseful when load directly
defined( 'BOZ_PHP' ) or die;
// load Bootstrap stuff
enqueue_js( 'jquery' );
enqueue_js( 'bootstrap' );
enqueue_css( 'bootstrap' );
enqueue_css( 'custom-css' );
?>
= __( "Authentication failed!" ) ?>
getSitePage( URL ); + return menu_entry( 'index' )->getURL(); } diff --git a/www/mailbox.php b/www/mailbox.php index 81d0138..5080bd0 100644 --- a/www/mailbox.php +++ b/www/mailbox.php @@ -1,132 +1,133 @@ . /* * This is the mailbox edit page */ // load framework require '../load.php'; // wanted domain and mailbox username list( $domain_name, $mailbox_username ) = url_parts( 2, 1 ); $domain = null; $mailbox = null; $mailbox_password = null; if( $mailbox_username ) { // retrieve the mailbox and its domain $mailbox = ( new MailboxFullAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'domain_active', 'mailbox_username', ] ) ->whereDomainName( $domain_name ) ->whereStr( 'mailbox_username', $mailbox_username ) ->whereMailboxIsEditable() ->queryRow(); // 404? $mailbox or PageNotFound::spawn(); // the mailbox has the domain stuff $domain = $mailbox; } else { // retrieve just the domain $domain = ( new DomainAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'domain_active', ] ) ->whereDomainName( $domain_name ) ->whereDomainIsEditable() ->queryRow(); // 404? $domain or PageNotFound::spawn(); } /* * Change the mailbox password */ if( $mailbox && is_action( 'mailbox-password-reset' ) ) { $mailbox_password = $mailbox->updateMailboxPassword(); } /* * Create the mailbox */ if( !$mailbox && is_action( 'mailbox-create' ) && isset( $_POST[ 'mailbox_username' ] ) ) { // TODO: check max. creation number in single domain props require_permission( 'edit-email-all' ); $_POST[ 'mailbox_username' ] = luser_input( $_POST[ 'mailbox_username' ], 64 ); $mailbox = ( new MailboxFullAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'mailbox_username', ] ) ->whereDomainName( $domain_name ) ->whereStr( 'mailbox_username', $_POST[ 'mailbox_username' ] ) ->queryRow(); if( !$mailbox ) { insert_row( 'mailbox', [ new DBCol( 'mailbox_username', $_POST[ 'mailbox_username' ], 's' ), new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ), ] ); } $mailbox = ( new MailboxFullAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'mailbox_username', ] ) ->whereDomainName( $domain_name ) ->whereStr( 'mailbox_username', $_POST[ 'mailbox_username' ] ) ->queryRow(); if( $mailbox ) { http_redirect( $mailbox->getMailboxPermalink( true ) ); } } // spawn header Header::spawn( [ + 'uid' => false, 'title-prefix' => __( "Mailbox" ), 'title' => $mailbox ? $mailbox->getMailboxAddress() : __( "create" ), 'breadcrumb' => [ new MenuEntry( null, $domain->getDomainPermalink(), $domain->getDomainName() ), ], ] ); // spawn the page content template( 'mailbox', [ 'mailbox' => $mailbox, 'mailbox_password' => $mailbox_password, 'domain' => $domain, ] ); // spawn the footer Footer::spawn(); diff --git a/www/mailforward.php b/www/mailforward.php index 92b3485..ad2e2a6 100644 --- a/www/mailforward.php +++ b/www/mailforward.php @@ -1,182 +1,183 @@ . /* * This is the single e-mail forwarding edit page */ // load framework require '../load.php'; // wanted informations $domain = null; $mailforwardfrom = null; // URL paramenters (maximum both domain and mailforward source, minimum just domain) list( $domain_name, $mailforwardfrom_username ) = url_parts( 2, 1 ); // eventually retrieve mailforward from database if( $mailforwardfrom_username ) { $mailforwardfrom = ( new MailforwardfromAPI ) ->select( [ 'domain.domain_ID', 'domain_name', 'mailforwardfrom.mailforwardfrom_ID', 'mailforwardfrom_username', ] ) ->whereDomainName( $domain_name ) ->whereMailforwardfromUsername( $mailforwardfrom_username ) ->whereDomainIsEditable() ->queryRow(); // 404 $mailforwardfrom or PageNotFound::spawn(); // recycle the mailforward object that has domain informations $domain = $mailforwardfrom; } // eventually retrieve domain from database if( ! $domain ) { $domain = ( new DomainAPI() ) ->select( [ 'domain.domain_ID', 'domain.domain_name', ] ) ->whereDomainName( $domain_name ) ->whereDomainIsEditable() ->queryRow(); // 404 $domain or PageNotFound::spawn(); } // save destination action if( is_action( 'mailforward-save' ) ) { // save source only during creation if( ! $mailforwardfrom ) { // sanitize if( ! isset( $_POST[ 'mailforwardfrom_username' ] ) ) { BadRequest::spawn( __( "missing parameter" ) ); } $username = luser_input( $_POST[ 'mailforwardfrom_username' ], 128 ); if( ! validate_mailbox_username( $username ) ) { BadRequest::spawn( __( "invalid mailbox name" ) ); } // check existence $mailforwardfrom_exists = ( new MailforwardfromAPI ) ->select( 1 ) ->whereDomain( $domain ) ->whereMailforwardfromUsername( $username ) ->queryRow(); // die if exists if( $mailforwardfrom_exists ) { BadRequest::spawn( __( "e-mail forwarding already existing" ) ); } // insert as new row insert_row( 'mailforwardfrom', [ new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ), new DBCol( 'mailforwardfrom_username', $username, 's' ), ] ); // POST/redirect/GET http_redirect( Mailforwardfrom::permalink( $domain->getDomainName(), $username, true ), 303 ); } } // delete action if( $mailforwardfrom ) { // action fired when deleting a whole mailforward if( is_action( 'mailforward-delete' ) ) { // drop th query( sprintf( "DELETE FROM %s WHERE domain_ID = %d AND mailforwardfrom_username = '%s'", T( 'mailforwardfrom' ), $mailforwardfrom->getDomainID(), $mailforwardfrom->getMailforwardfromUsername() ) ); // POST/redirect/GET http_redirect( $domain->getDomainPermalink( true ), 303 ); } // action fired when adding/removing a mailforward if( ( is_action( 'mailforwardto-add' ) || is_action( 'mailforwardto-remove' ) ) && isset( $_POST[ 'address' ] ) ) { $address = require_email( $_POST[ 'address' ] ); if( $address === $mailforwardfrom->getMailforwardfromAddress() ) { BadRequest::spawn( __( "do not try to create a loop" ) ); } $existing_address = ( new MailforwardtoAPI() ) ->whereMailforwardfrom( $mailforwardfrom ) ->whereMailforwardtoAddress( $address ) ->queryRow(); // action fired when removing a mailforward if( is_action( 'mailforwardto-remove' ) && $existing_address ) { query( sprintf( "DELETE FROM %s WHERE mailforwardfrom_ID = %d and mailforwardto_address = '%s'", T( 'mailforwardto' ), $mailforwardfrom->getMailforwardfromID(), esc_sql( $address ) ) ); } // action fired when adding a mailforward if( is_action( 'mailforwardto-add' ) && ! $existing_address ) { insert_row( 'mailforwardto', [ new DBCol( 'mailforwardfrom_ID', $mailforwardfrom->getMailforwardfromID(), 'd' ), new DBCol( 'mailforwardto_address', $address, 's' ), ] ); } } } // spawn header Header::spawn( [ + 'uid' => false, 'title-prefix' => __( "E-mail forwarding" ), 'title' => $mailforwardfrom ? $mailforwardfrom->getMailforwardfromAddress() : __( "create" ), 'breadcrumb' => [ new MenuEntry( null, $domain->getDomainPermalink(), $domain->getDomainName() ), ], ] ); // spawn the page content template( 'mailforward', [ 'domain' => $domain, 'mailforwardfrom' => $mailforwardfrom, ] ); // spawn the footer Footer::spawn();