diff --git a/www/activity.php b/www/activity.php
index dec810b..387245e 100644
--- a/www/activity.php
+++ b/www/activity.php
@@ -1,38 +1,41 @@
.
/*
* This is the homepage of your hosting panel
*/
// load framework
require '../load.php';
+// this page is not public
+require_permission( 'backend' );
+
// spawn header
Header::spawn();
?>
[
'limit' => 200,
],
] ) ?>
.
/*
* This is the domain edit page
*/
// load framework
require '../load.php';
+// this page is not public
+require_permission( 'backend' );
+
// wanted domain
list( $domain_name ) = url_parts( 1, 0 );
$domain = null;
if( $domain_name ) {
// retrieve domain
$domain = ( new DomainAPI() )
->whereDomainName( $domain_name )
->whereDomainIsEditable()
->joinPlan( 'LEFT' )
->queryRow();
// 404?
$domain or PageNotFound::spawn();
} else {
// try to create
require_permission( 'edit-domain-all' );
if( is_action( 'add-domain' ) && isset( $_POST[ 'domain_name' ] ) ) {
// trim and normalize to max length
$domain_name = luser_input( $_POST[ 'domain_name' ], 64 );
// existing domain
$existing = ( new DomainAPI() )
->whereDomainName( $domain_name )
->queryRow();
// go to the existing one
if( $existing ) {
http_redirect( $existing->getDomainPermalink() );
}
query( 'START TRANSACTION' );
// insert this new domain
insert_row( Domain::T, [
new DBCol( 'domain_name', $domain_name, 's' ),
new DBCol( 'domain_active', 1, 'd' ),
new DBCol( 'domain_born', 'NOW()', '-' ),
] );
// this Domain ID
$domain_ID = last_inserted_ID();
// add this event in the log
APILog::insert( [
'family' => 'domain',
'action' => 'create',
'domain' => $domain_ID,
] );
query( 'COMMIT' );
// go to the new domain
http_redirect( Domain::permalink( $domain_name, true ) );
}
}
// spawn header
Header::spawn( [
'uid' => false,
'title-prefix' => __( "Domain" ),
'title' => $domain_name ? $domain_name : __( "Add" ),
] );
if( $domain ) {
// spawn the domain template
template( 'domain', [
'domain' => $domain,
'plan' => $domain,
] );
} else {
// form to create the domain
template( 'domain-create' );
}
// spawn the footer
Footer::spawn();
diff --git a/www/index.php b/www/index.php
index f55416a..a183fe9 100644
--- a/www/index.php
+++ b/www/index.php
@@ -1,95 +1,98 @@
.
/*
* This is the homepage of your hosting panel
*/
// load framework
require '../load.php';
+// this page is not public
+require_permission( 'backend' );
+
// spawn header
Header::spawn( [
'breadcrumb' => false,
] );
// user domains
$domains = ( new DomainAPI() )
->select( [
'domain.domain_ID',
'domain_name',
'domain_active',
] )
->whereDomainIsEditable()
->orderBy( 'domain_name' )
->queryGenerator();
?>
valid() ): ?>
-
domain_active ): ?>
= HTML::a(
$domain->getDomainPermalink(),
$domain->domain_name
) ?>
= esc_html( $domain->domain_name ) ?>
= HTML::a(
menu_entry( 'user-list' )->getURL(),
__( "Users" )
) ?>
= HTML::a(
menu_entry( 'activity' )->getURL(),
__( "Last Activity" )
) ?>
.
/*
* This is the mailbox edit page
*/
// load framework
require '../load.php';
+// this page is not public
+require_permission( 'backend' );
+
// wanted domain and mailbox username
list( $domain_name, $mailbox_username ) = url_parts( 2, 1 );
// some useful information
$domain = null;
$mailbox = null;
$plan = null;
$mailbox_password = null;
// check if the page is about a specific Mailbox
if( $mailbox_username ) {
// retrieve the mailbox and its domain and its Plan
$mailbox = ( new MailboxFullAPI() )
->joinPlan( 'LEFT' )
->whereDomainName( $domain_name )
->whereMailboxUsername( $mailbox_username )
->whereMailboxIsEditable()
->queryRow();
// 404?
$mailbox or PageNotFound::spawn();
// the mailbox object has the domain stuff - recycle it
$domain = $mailbox;
// the mailbox object has the Plan stuff - recycle it
$plan = $mailbox;
} else {
// retrieve just the domain and its Plan
$domain = ( new DomainAPI() )
->whereDomainName( $domain_name )
->whereDomainIsEditable()
->joinPlan( 'LEFT' )
->queryRow();
// 404?
$domain or PageNotFound::spawn();
// the domain object has the Plan stuff - recycle it
$plan = $domain;
}
// does the user want to create a Mailbox?
if( !$mailbox ) {
// count the actual number of Domain Mailbox(es)
$mailbox_count = (int)
( new MailboxAPI() )
->select( 'COUNT(*) count' )
->whereDomain( $domain )
->queryValue( 'count' );
// check if I can add another Mailbox
if( $mailbox_count >= $plan->getPlanMailboxes() && !has_permission( 'edit-email-all' ) ) {
BadRequest::spawn( __( "Your Plan does not allow this action" ), 401 );
}
}
/*
* Change the mailbox password
*/
if( $mailbox && is_action( 'mailbox-password-reset' ) ) {
$mailbox_password = $mailbox->updateMailboxPassword();
}
/**
* Eventually save the notes
*/
if( $mailbox && is_action( 'save-mailbox-notes' ) ) {
// read the description
$description = $_POST['mailbox_description'] ?? null;
query( 'START TRANSACTION' );
// save the description
( new MailboxAPI() )
->whereMailbox( $mailbox )
->update( [
'mailbox_description' => $description,
] );
// remember this action in the registry
APILog::insert( [
'family' => 'mailbox',
'action' => 'description.change',
'mailbox' => $mailbox,
'domain' => $domain,
] );
query( 'COMMIT' );
// POST -> redirect -> GET
http_redirect( $mailbox->getMailboxPermalink() );
}
/*
* Create the mailbox
*/
if( !$mailbox && is_action( 'mailbox-create' ) && isset( $_POST['mailbox_username'] ) ) {
// assure that the username is not too long
$_POST['mailbox_username'] = luser_input( $_POST['mailbox_username'], 64 );
// check if the mailbox already exist
$mailbox_exists = ( new MailboxFullAPI() )
->select( 1 )
->whereDomainName( $domain_name )
->whereMailboxUsername( $_POST['mailbox_username'] )
->queryRow();
// check if we can create the mailbox
if( !$mailbox_exists ) {
// assign a damn temporary password
$mailbox_password = generate_password();
$mailbox_password_safe = Mailbox::encryptPassword( $mailbox_password );
query( 'START TRANSACTION' );
// really create the mailbox
insert_row( 'mailbox', [
new DBCol( 'mailbox_username', $_POST['mailbox_username'], 's' ),
new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ),
new DBCol( 'mailbox_password', $mailbox_password_safe, 's' ),
] );
// register this event in the registry
APILog::insert( [
'family' => 'mailbox',
'action' => 'create',
'domain' => $domain,
'mailbox' => last_inserted_ID(),
] );
query( 'COMMIT' );
}
// POST -> redirect -> GET
http_redirect( Mailbox::permalink(
$domain->getDomainName(),
$_POST['mailbox_username']
) );
}
// 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,
'plan' => $plan,
] );
// spawn the footer
Footer::spawn();
diff --git a/www/mailforward.php b/www/mailforward.php
index 383899a..71c9a22 100644
--- a/www/mailforward.php
+++ b/www/mailforward.php
@@ -1,239 +1,242 @@
.
/*
* This is the single e-mail forwarding edit page
*/
// load framework
require '../load.php';
+// this page is not public
+require_permission( 'backend' );
+
// 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 MailforwardfromQuery() )
->select( [
'domain.domain_ID',
'domain_name',
'mailforwardfrom.mailforwardfrom_ID',
'mailforwardfrom_username',
] )
->joinDomain()
->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 MailforwardfromQuery() )
->select( 1 )
->whereDomain( $domain )
->whereMailforwardfromUsername( $username )
->queryRow();
// die if exists
if( $mailforwardfrom_exists ) {
BadRequest::spawn( __( "e-mail forwarding already existing" ) );
}
query( 'START TRANSACTION' );
// insert as new row
insert_row( 'mailforwardfrom', [
new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ),
new DBCol( 'mailforwardfrom_username', $username, 's' ),
] );
// remember this action in the registry
APILog::insert( [
'family' => 'mailforward',
'action' => 'create',
'domain' => $domain,
'mailforwardfrom' => last_inserted_ID(),
] );
query( 'COMMIT' );
// 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' ) ) {
query( 'START TRANSACTION' );
// mark a deletion on this Domain
APILog::insert( [
'family' => 'mailforward',
'action' => 'delete',
'domain' => $domain,
] );
// drop the foreign key constraints
// See https://gitpull.it/T518
( new QueryLog() )
->whereMailforwardfrom( $mailforwardfrom )
->update( [
'mailforwardfrom_ID' => null,
] );
// drop the existing one
( new MailforwardfromQuery() )
->whereMailforwardfrom( $mailforwardfrom )
->delete();
query( 'COMMIT' );
// 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( 'START TRANSACTION' );
// TODO refactor with query builder
query( sprintf(
"DELETE FROM %s WHERE mailforwardfrom_ID = %d and mailforwardto_address = '%s'",
T( 'mailforwardto' ),
$mailforwardfrom->getMailforwardfromID(),
esc_sql( $address )
) );
// remember that we removed an address
APILog::insert( [
'family' => 'mailforward',
'action' => 'remove.destination',
'domain' => $domain,
'mailforwardfrom' => $mailforwardfrom,
] );
query( 'COMMIT' );
}
// action fired when adding a mailforward
if( is_action( 'mailforwardto-add' ) && ! $existing_address ) {
query( 'START TRANSACTION' );
insert_row( 'mailforwardto', [
new DBCol( 'mailforwardfrom_ID', $mailforwardfrom->getMailforwardfromID(), 'd' ),
new DBCol( 'mailforwardto_address', $address, 's' ),
] );
// remember that we added an address
APILog::insert( [
'family' => 'mailforward',
'action' => 'add.destination',
'domain' => $domain,
'mailforwardfrom' => $mailforwardfrom,
] );
query( 'COMMIT' );
}
}
}
// 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();
diff --git a/www/profile.php b/www/profile.php
index 6fbcbbf..d8ff0e2 100644
--- a/www/profile.php
+++ b/www/profile.php
@@ -1,83 +1,83 @@
.
/*
* This is the user profile page
*/
// load framework
require '../load.php';
-// must be logged
-require_permission( 'read' );
+// this page is not public
+require_permission( 'backend' );
// myself
$user = get_user();
// edit whatever user
if( isset( $_SERVER[ 'PATH_INFO' ] ) ) {
require_permission( 'edit-all-user' );
list( $user_uid ) = url_parts( 1 );
$user = Sessionuser::factoryFromUID( $user_uid )
->queryRow();
if( ! $user ) {
PageNotFound::spaqn();
}
}
// spawn header
Header::spawn( [
'title' => __( "Profile" ),
] );
// user e-mail
$email = $user->get( 'user_email' );
// handle send user password action
if( is_action( 'send-user-password' ) ) {
// generate
$password = generate_password();
// e-mail body
$mail_content = template_content( 'mail-user-password', [
'email' => $email,
'name' => $user->get( 'user_name' ),
'uid' => $user->get( 'user_uid' ),
'surname' => $user->get( 'user_surname' ),
'password' => $password,
] );
// update
query_update( 'user', [
new DBCol( 'user_password', Sessionuser::encryptPassword( $password ), 's' ),
], sprintf(
'user_ID = %d',
$user->get( 'user_ID' )
) );
// send
send_email( __( "Password reset" ), $mail_content, $email );
}
// spawn the profile page
template( 'profile', [ 'email' => $email ] );
// spawn footer
Footer::spawn();
diff --git a/www/user-list.php b/www/user-list.php
index 87cf4f7..8c93daf 100644
--- a/www/user-list.php
+++ b/www/user-list.php
@@ -1,77 +1,80 @@
.
/*
* This is the domain edit page
*/
// load framework
require '../load.php';
+// this page is not public
+require_permission( 'backend' );
+
// spawn header
Header::spawn( [
'title' => __( "Users" ),
] );
$pager = new UserPager();
?>
= esc_html( __( "Login" ) ) ?> |
= esc_html( __( "Surname" ) ) ?> |
= esc_html( __( "Name" ) ) ?> |
= esc_html( __( "Role" ) ) ?> |
createPagedQuery()->queryGenerator() as $user ): ?>
= HTML::a(
$user->getUserPermalink(),
$user->getUserUID()
) ?> |
= esc_html( $user->getUserSurname() ) ?> |
= esc_html( $user->getUserName() ) ?> |
= esc_html( $user->getUserRoleLabel() ) ?> |
= __( "Add" ) ?>
.
/*
* This is the single User creation/edit page
*/
// load framework
require '../load.php';
-// require the permission to see the backend
+// this page is not public
require_permission( 'backend' );
// wanted informations
$user = null;
// URL paramenters (user_uid)
list( $user_uid ) = url_parts( 1, 0 );
// eventually retrieve mailforward from database
if( $user_uid ) {
$user = ( new UserAPI() )
->whereUserUID( $user_uid )
->whereUserIsEditable()
->queryRow();
// 404
if( !$user || !$user->isUserEditable() ) {
PageNotFound::spawn();
}
} else {
// to create an FTP user, must edit all FTP users
require_permission( 'edit-user-all' );
}
// register save User action
if( is_action( 'save-user' ) ) {
$email = $_POST['email'] ?? null;
$uid = $_POST['uid'] ?? null;
$name = $_POST['name'] ?? null;
$surname = $_POST['surname'] ?? null;
if( $email && $uid && $name && $surname ) {
$email = (string) $email;
// data to be saved
$data = [];
$data['user_email'] = $email;
$data['user_name'] = $name;
$data['user_surname'] = $surname;
if( $user ) {
// update existing User
( new UserAPI() )
->whereUser( $user )
->update( $data );
} else {
// insert new User
$data['user_uid'] = $uid;
$data['user_active'] = 0; // disable login as default
$data['user_password'] = '!'; // assign an invalid password
$data['user_role'] = 'user'; // assign low privileges
$data[] = new DBCol( 'user_registration_date', 'NOW()', '-' );
( new UserAPI() )
->insertRow( $data );
}
// POST -> redirect -> GET (See Other)
http_redirect( User::permalink( $uid ), 303 );
}
}
// end register Save user action
// add a Domain to the user
if( is_action( 'add-domain' ) ){
// check for permissions
if( !has_permission( 'edit-user-all' ) ) {
error_die( "Not authorized to add a Domain" );
}
// get the Domain by name
$domain_name = $_POST['domain_name'] ?? null;
if( !$domain_name ) {
die( "Please fill that damn Domain name" );
}
// search the Domain name
$domain =
( new DomainAPI() )
->whereDomainName( $domain_name )
->queryRow();
query( 'START TRANSACTION' );
// domain ID to be assigned to the User
$domain_ID = null;
// does the Domain already exist?
if( $domain ) {
$domain_ID = $domain->getDomainID();
} else {
// can I add this Domain?
if( has_permission( 'edit-domain-all' ) ) {
// add this Domain
( new DomainAPI() )
->insertRow( [
'domain_name' => $domain_name,
'domain_active' => 1,
new DBCol( 'domain_born', 'NOW()', '-' ),
] );
$domain_ID = last_inserted_ID();
}
}
if( $domain_ID ) {
$is_domain_mine =
( new DomainUserAPI() )
->whereUserIsMe()
->whereDomainID( $domain_ID )
->queryRow();
// is it already mine?
if( !$is_domain_mine ) {
// associate this domain to myself
( new DomainUserAPI() )
->insertRow( [
'domain_ID' => $domain_ID,
'user_ID' => $user->getUserID(),
new DBCol( 'domain_user_creation_date', 'NOW()', '-' ),
] );
}
} else {
die( "this Domain is not registered and can't be added" );
}
query( 'COMMIT' );
}
// end add Domain to User
// register action to generate a new password
$new_password = null;
if( is_action( 'change-password' ) && $user ) {
// generate a new password and save
$new_password = generate_password();
$encrypted = User::encryptPassword( $new_password );
( new UserAPI() )
->whereUser( $user )
->update( [
User::IS_ACTIVE => 1,
User::PASSWORD => $encrypted,
] );
// do not refresh the page
}
// expose the User domains
$user_domains = [];
if( $user ) {
// get User domains
$user_domains =
( new DomainUserAPI() )
->joinDomain()
->whereUser( $user )
->orderByDomainName()
->queryGenerator();
}
// spawn header
Header::spawn( [
'uid' => false,
'title-prefix' => __( "User" ),
'title' => $user
? $user->getUserUID()
: __( "create" ),
] );
// spawn the page content
template( 'user', [
'user' => $user,
'new_password' => $new_password,
'user_domains' => $user_domains,
] );
// spawn the footer
Footer::spawn();