Add tailscale auth

This commit is contained in:
Karl Cordes 2025-08-18 21:10:33 +10:00
parent 97dbeb6a1c
commit e469e14ae1
2 changed files with 105 additions and 3 deletions

View file

@ -183,6 +183,28 @@ Configure::write('Security.salt', 'uiPxR3MzVXAID5zucbxLdxP4TX33buPoCWZr4JfroGoaE
Configure::write('Acl.classname', 'DbAcl');
Configure::write('Acl.database', 'default');
/**
* Tailscale Authentication Configuration
*
* Enable Tailscale HTTP header authentication support
* When enabled, the system will check for Tailscale authentication headers
* before falling back to HTTP Basic Auth
*/
Configure::write('Tailscale.enabled', true);
/**
* Auto-create users from Tailscale authentication
* When enabled, users authenticated via Tailscale headers will be
* automatically created if they don't exist in the database
*/
Configure::write('Tailscale.autoCreateUsers', false);
/**
* Default access level for auto-created Tailscale users
* Options: 'user', 'manager', 'admin'
*/
Configure::write('Tailscale.defaultAccessLevel', 'user');

View file

@ -10,8 +10,66 @@ class AppController extends Controller {
var $helpers = array('Javascript', 'Time', 'Html', 'Form');
function beforeFilter() {
// Find the user that matches the HTTP basic auth user
$user = $this->User->find('first', array('recursive' => 0, 'conditions' => array('User.username'=>$_SERVER["PHP_AUTH_USER"])));
$user = null;
// Check if Tailscale authentication is enabled
if (Configure::read('Tailscale.enabled')) {
// Check for Tailscale authentication headers
$tailscaleLogin = isset($_SERVER['HTTP_TAILSCALE_USER_LOGIN']) ? $_SERVER['HTTP_TAILSCALE_USER_LOGIN'] : null;
$tailscaleName = isset($_SERVER['HTTP_TAILSCALE_USER_NAME']) ? $_SERVER['HTTP_TAILSCALE_USER_NAME'] : null;
if ($tailscaleLogin) {
// Try to find user by email address from Tailscale header
$user = $this->User->find('first', array(
'recursive' => 0,
'conditions' => array('User.email' => $tailscaleLogin)
));
// If user not found and auto-creation is enabled, create a new user
if (!$user && Configure::read('Tailscale.autoCreateUsers')) {
// Parse the name
$firstName = '';
$lastName = '';
if ($tailscaleName) {
$nameParts = explode(' ', $tailscaleName);
$firstName = $nameParts[0];
if (count($nameParts) > 1) {
array_shift($nameParts);
$lastName = implode(' ', $nameParts);
}
}
$userData = array(
'User' => array(
'email' => $tailscaleLogin,
'username' => $tailscaleLogin,
'first_name' => $firstName,
'last_name' => $lastName,
'type' => 'user',
'access_level' => Configure::read('Tailscale.defaultAccessLevel'),
'enabled' => 1,
'by_vault' => 0
)
);
$this->User->create();
if ($this->User->save($userData)) {
$user = $this->User->find('first', array(
'recursive' => 0,
'conditions' => array('User.id' => $this->User->id)
));
}
}
}
}
// Fall back to HTTP basic auth if no Tailscale auth or user not found
if (!$user && isset($_SERVER["PHP_AUTH_USER"])) {
$user = $this->User->find('first', array(
'recursive' => 0,
'conditions' => array('User.username' => $_SERVER["PHP_AUTH_USER"])
));
}
$this->set("currentuser", $user);
if($this->RequestHandler->isAjax()) {
@ -52,7 +110,29 @@ class AppController extends Controller {
* @return array - the currently logged in user.
*/
function getCurrentUser() {
$user = $this->User->find('first', array('recursive' => 0, 'conditions' => array('User.username'=>$_SERVER["PHP_AUTH_USER"])));
$user = null;
// Check if Tailscale authentication is enabled
if (Configure::read('Tailscale.enabled')) {
$tailscaleLogin = isset($_SERVER['HTTP_TAILSCALE_USER_LOGIN']) ? $_SERVER['HTTP_TAILSCALE_USER_LOGIN'] : null;
if ($tailscaleLogin) {
// Try to find user by email address from Tailscale header
$user = $this->User->find('first', array(
'recursive' => 0,
'conditions' => array('User.email' => $tailscaleLogin)
));
}
}
// Fall back to HTTP basic auth if no Tailscale auth or user not found
if (!$user && isset($_SERVER["PHP_AUTH_USER"])) {
$user = $this->User->find('first', array(
'recursive' => 0,
'conditions' => array('User.username' => $_SERVER["PHP_AUTH_USER"])
));
}
return $user;
}