Skip to content

Commit

Permalink
Implemented SSO support for server managers (#1888)
Browse files Browse the repository at this point in the history
* Implemented SSO support for server managers

Co-Authored-By: Aziz Ozbek <aziza2772@gmail.com>

* Fixed typos

* Fixed a few untranslatable strings

---------

Co-authored-by: Aziz Ozbek <aziza2772@gmail.com>
  • Loading branch information
BelleNottelling and azizozbek committed Nov 26, 2023
1 parent 4676e02 commit b94d932
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 67 deletions.
8 changes: 6 additions & 2 deletions src/library/Server/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,20 @@ protected function init()
/**
* Returns the login URL for the server. (ex: panel.example.com)
*
* @param null|Server_Account $account Either the related `Server_Account` which can be used to generate an SSO link or `null`.
*
* @return string
*/
abstract public function getLoginUrl();
abstract public function getLoginUrl(?Server_Account $account);

/**
* Returns the login URL for the server for reseller accounts.
*
* @param null|Server_Account $account Either the related `Server_Account` which can be used to generate an SSO link or `null`.
*
* @return string
*/
abstract public function getResellerLoginUrl();
abstract public function getResellerLoginUrl(?Server_Account $account);

/**
* Used to test the connection to the server and verify the server configuration is correct.
Expand Down
4 changes: 2 additions & 2 deletions src/library/Server/Manager/CWP.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ public static function getForm()
/**
* We can actually generate a direct log-in link from CWP, but I'm not sure if that's a secure thing to do here.
*/
public function getLoginUrl()
public function getLoginUrl(?Server_Account $account = null)
{
$host = $this->_config['host'];
return 'https://' . $host . ':2083';
}

public function getResellerLoginUrl()
public function getResellerLoginUrl(?Server_Account $account = null)
{
$host = $this->_config['host'];
return 'https://' . $host . ':2031';
Expand Down
4 changes: 2 additions & 2 deletions src/library/Server/Manager/Custom.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static function getForm()
*
* @return string
*/
public function getLoginUrl()
public function getLoginUrl(?Server_Account $account = null)
{
return 'http://www.google.com?q=cpanel';
}
Expand All @@ -44,7 +44,7 @@ public function getLoginUrl()
* Returns link to reseller account management
* @return string
*/
public function getResellerLoginUrl()
public function getResellerLoginUrl(?Server_Account $account = null)
{
return 'http://www.google.com?q=whm';
}
Expand Down
4 changes: 2 additions & 2 deletions src/library/Server/Manager/Directadmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ public function _getPort()
return is_numeric($this->_config['port']) ? $this->_config['port'] : '2222';
}

public function getLoginUrl() : string
public function getLoginUrl(?Server_Account $account = null): string
{
$protocol = $this->_config['secure'] ? 'https://' : 'http://';
return $protocol . $this->_config['host'] . ':'. $this -> _getPort();
}

public function getResellerLoginUrl()
public function getResellerLoginUrl(?Server_Account $account = null)
{
return $this->getLoginUrl();
}
Expand Down
4 changes: 2 additions & 2 deletions src/library/Server/Manager/Hestia.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static function getForm(): array
*
* @return string
*/
public function getLoginUrl()
public function getLoginUrl(?Server_Account $account = null)
{
return 'https://' . $this->_config['host'] . ':' . $this->_getPort() . '/';
}
Expand All @@ -68,7 +68,7 @@ public function getLoginUrl()
*
* @return string
*/
public function getResellerLoginUrl()
public function getResellerLoginUrl(?Server_Account $account = null)
{
return $this->getLoginUrl();
}
Expand Down
17 changes: 10 additions & 7 deletions src/library/Server/Manager/Plesk.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache-2.0
*/

use PleskX\Api\Client;

class Server_Manager_Plesk extends Server_Manager
{
private ?\PleskX\Api\Client $_client = null;
Expand All @@ -28,13 +26,18 @@ public static function getForm()
];
}

public function getLoginUrl()
{
public function getLoginUrl(?Server_Account $account = null): string
{
$protocol = $this->_config['secure'] ? 'https' : 'http';
return $protocol . "://" . $this->_config['host'] . ':' . $this->_config['port'];
}
$url = $protocol . "://" . $this->_config['host'] . ':' . $this->_config['port'];
if ($account) {
$sessionId = $this->_client->session()->create($account->getUsername(), $_SERVER['REMOTE_ADDR']);
$url .= '/enterprise/rsession_init.php?PHPSESSID=' . $sessionId;
}
return $url;
}

public function getResellerLoginUrl()
public function getResellerLoginUrl(?Server_Account $account = null)
{
return $this->getLoginUrl();
}
Expand Down
4 changes: 2 additions & 2 deletions src/library/Server/Manager/Whm.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ public function init()
$this->_config['port'] = empty($this->_config['port']) ? '2087' : $this->_config['port'];
}

public function getLoginUrl()
public function getLoginUrl(?Server_Account $account = null)
{
$host = $this->_config['host'];
return 'http://'.$host.'/cpanel';
}

public function getResellerLoginUrl()
public function getResellerLoginUrl(?Server_Account $account = null)
{
$host = $this->_config['host'];
return 'http://'.$host.'/whm';
Expand Down
2 changes: 1 addition & 1 deletion src/modules/Client/html_admin/mod_client_manage.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -851,5 +851,5 @@
function onAfterInvoicePrepared(id) {
bb.redirect("{{ 'invoice/manage/'|alink }}/" + id);
}
</script>
</script>
{% endblock %}
16 changes: 16 additions & 0 deletions src/modules/Servicehosting/Api/Client.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Copyright 2022-2023 FOSSBilling
* Copyright 2011-2021 BoxBilling, Inc.
Expand Down Expand Up @@ -61,6 +62,21 @@ public function hp_get_pairs($data)
return $this->getService()->getHpPairs();
}

/**
* Returns the login URL for a given order ID.
* If the associated server manager supports SSO, an SSO link will be given.
* Will automatically return either a reseller URL or a standard URL depending on the order config.
*
* @param array $data An array containing the API request data. Should have a key named `order_id` containing the order's ID.
*
* @return string
*/
public function get_login_url(array $data): string
{
[$order, $s] = $this->_getService($data);
return $this->getService()->generateLoginUrl($s);
}

public function _getService($data)
{
if (!isset($data['order_id'])) {
Expand Down
28 changes: 27 additions & 1 deletion src/modules/Servicehosting/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -923,19 +923,45 @@ public function getServerManagerWithLog(\Model_ServiceHostingServer $model, \Mod
return $manager;
}

/**
* Returns both the standard and reseller login URLs.
* Will not generate SSO links.
*
* @param \Model_ServiceHostingServer $model
*
* @return string[]|false[]
*/
public function getMangerUrls(\Model_ServiceHostingServer $model)
{
try {
$m = $this->getServerManager($model);

return [$m->getLoginUrl(), $m->getResellerLoginUrl()];
return [$m->getLoginUrl(null), $m->getResellerLoginUrl(null)];
} catch (\Exception $e) {
error_log('Error while retrieving cPanel url: ' . $e->getMessage());
}

return [false, false];
}

/**
* Generates either a reseller or standard login link for a given order.
* If the server manager supports SSO, an SSO link will be returned.
*
* @param \Model_ServiceHosting $model
*
* @return string
*/
public function generateLoginUrl(\Model_ServiceHosting $model)
{
[$adapter, $account] = $this->_getAM($model);
if ($model->reseller) {
return $adapter->getResellerLoginUrl($account);
} else {
return $adapter->getLoginUrl($account);
}
}

public function prependOrderConfig(\Model_Product $product, array $data)
{
[$sld, $tld] = $this->_getDomainTuple($data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,14 @@
{% if service.domain_order_id %}
<a class="btn btn-primary" href="{{ '/order/service/manage'|link }}/{{ service.domain_order_id }}">{{ 'Manage domain'|trans }}</a>
{% endif %}
<a class="btn btn-primary" href="{{ server.cpanel_url }}" target="_blank">{{ 'Jump to cPanel'|trans }}</a>
{% if service.reseller %}
<a class="btn btn-primary" href="{{ server.reseller_cpanel_url }}" target="_blank">{{ 'Reseller control panel'|trans }}</a>
{% endif %}
<a class="btn btn-primary api-link" href="{{ 'api/client/servicehosting/get_login_url'|link({ 'order_id': order.id, 'CSRFToken': CSRFToken }) }}" data-api-jsonp="onAfterLoginLinkCreated">{{ 'Login to control panel'|trans }}</a>
</div>
</div>
</div>
{# Hosting password #}
<div class="tab-pane fade" role="tabpanel" id="password">
<h3>{{ 'Change your FTP/cPanel/SSH password.'|trans }}</h3>
<form action="" method="post" id="change-password">
<form class="api-form" action="{{ 'api/client/servicehosting/change_password'|link }}" method="post" data-api-msg="{{ 'Password changed'|trans }}">
<input type="hidden" name="CSRFToken" value="{{ CSRFToken }}"/>
<fieldset>
<div class="control-group">
Expand Down Expand Up @@ -112,7 +109,7 @@
{# Hosting domain #}
<div class="tab-pane fade" role="tabpanel" id="domain">
<h3>{{ 'Change domain'|trans }}</h3>
<form action="" method="post" id="change-domain">
<form class="api-form" action="{{ 'api/client/servicehosting/change_domain'|link }}" method="post" data-api-msg="{{ 'Domain name changed'|trans }}">
<input type="hidden" name="CSRFToken" value="{{ CSRFToken }}"/>
<fieldset>
<div class="control-group">
Expand All @@ -134,7 +131,7 @@
{# Hosting username #}
<div class="tab-pane fade" role="tabpanel" id="username">
<h3>{{ 'Change username'|trans }}</h3>
<form action="" method="post" id="change-username">
<form class="api-form" action="{{ 'api/client/servicehosting/change_username'|link }}" method="post" data-api-msg="{{ 'Username changed'|trans }}">
<input type="hidden" name="CSRFToken" value="{{ CSRFToken }}"/>
<fieldset>
<div class="control-group">
Expand All @@ -159,44 +156,9 @@

{% block js %}
<script type="text/javascript">
$(function() {
$('#change-domain').on('submit', function(event) {
bb.post(
'client/servicehosting/change_domain',
$(this).serialize(),
function(result) {
bb.msg('Domain name was changed');
}
);
return false;
});
$('#change-username').on('submit', function(event) {
bb.post(
'client/servicehosting/change_username',
$(this).serialize(),
function(result) {
bb.msg('Account Username was changed');
}
);
return false;
});
$('#change-password').on('submit', function(event) {
bb.post(
'client/servicehosting/change_password',
$(this).serialize(),
function(result) {
bb.msg('Account Password was changed');
}
);
return false;
});
});
function onAfterLoginLinkCreated(url){
window.open(url, "_blank");
}
</script>
{% endblock %}
{% endif %}
2 changes: 1 addition & 1 deletion src/themes/huraga/html/layout_default.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
<li class="nav-item">
{% if client %}
<div class="dropdown">
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown"aria-expanded="false">
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<img class="img-fluid rounded-circle" alt="{{ profile.first_name }} {{ profile.last_name }} gravatar" src="{{ profile.email|gravatar(60) }}" height="25px" width="25px">
{% if profile.company %}
<span>{{ profile.first_name }} {{ profile.last_name }}|{{ profile.company }}</span>
Expand Down

0 comments on commit b94d932

Please sign in to comment.