-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,338 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers; | ||
|
||
use Illuminate\Http\Request; | ||
use Illuminate\Support\Facades\App; | ||
use Illuminate\Support\Facades\Log; | ||
use Barryvdh\Debugbar\Facade as Debugbar; | ||
use App\Models\CardDAV\MonicaAddressBookRoot; | ||
use App\Models\CardDAV\Backends\MonicaSabreBackend; | ||
use App\Models\CardDAV\Backends\MonicaCardDAVBackend; | ||
use App\Models\CardDAV\Backends\MonicaPrincipleBackend; | ||
|
||
class CardDAVController extends Controller | ||
{ | ||
/** | ||
* Display the specified resource. | ||
*/ | ||
public function init(Request $request) | ||
{ | ||
// Disable debugger for caldav output | ||
Debugbar::disable(); | ||
|
||
// Initiate custom backends for link between Sabre and Monica | ||
$authBackend = new MonicaSabreBackend(); // Authentication | ||
$principalBackend = new MonicaPrincipleBackend(); // User rights | ||
$carddavBackend = new MonicaCardDAVBackend(); // Contacts | ||
|
||
$nodes = [ | ||
new \Sabre\DAVACL\PrincipalCollection($principalBackend), | ||
new MonicaAddressBookRoot($principalBackend, $carddavBackend), | ||
]; | ||
|
||
// Initiate Sabre server | ||
$server = new \Sabre\DAV\Server($nodes); | ||
$server->setBaseUri('/carddav'); | ||
$server->debugExceptions = true; | ||
|
||
// Modify Laravel request to include trailing slash. Laravel removes it by default, Sabre needs it. | ||
$server->httpRequest->setUrl(str_replace('/carddav', '/carddav/', $request->getRequestUri())); | ||
$server->httpRequest->setBaseUrl('/carddav/'); | ||
|
||
// Testing needs method verb to be set manually | ||
if (App::environment('testing')) { | ||
$server->httpRequest->setMethod($request->method()); | ||
} | ||
|
||
// Add required plugins | ||
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend, 'SabreDAV')); | ||
|
||
// CardDAV plugin | ||
$server->addPlugin(new \Sabre\CardDAV\Plugin()); | ||
|
||
// ACL plugnin | ||
$aclPlugin = new \Sabre\DAVACL\Plugin(); | ||
$aclPlugin->allowUnauthenticatedAccess = false; | ||
$server->addPlugin($aclPlugin); | ||
|
||
// In debug mode add browser plugin | ||
if (App::environment('local')) { | ||
$server->addPlugin(new \Sabre\DAV\Browser\Plugin()); | ||
} | ||
|
||
// Execute requests and catch output | ||
// We do this because laravel always sends a 200 back, but we need to use the StatusCode and of Sabre | ||
ob_start(); | ||
$server->exec(); | ||
$status = $server->httpResponse->getStatus(); | ||
$content = ob_get_contents(); | ||
$headers = $server->httpResponse->getHeaders(); | ||
ob_end_clean(); | ||
|
||
// Return response through laravel | ||
Log::debug(__CLASS__.' init', [ | ||
'status' => $status, | ||
'content' => $content, | ||
]); | ||
|
||
return response($content, $status) | ||
->withHeaders($headers); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
|
||
namespace App\Http\Middleware; | ||
|
||
use Closure; | ||
use Illuminate\Auth\AuthManager; | ||
|
||
/** | ||
* Authenticate user with Basic Authentication, with two methods: | ||
* - Basic auth: login + password | ||
* - Bearer on basic: login + api token. | ||
*/ | ||
class AuthenticateWithTokenOnBasicAuth | ||
{ | ||
/** | ||
* The guard factory instance. | ||
* | ||
* @var AuthManager | ||
*/ | ||
protected $auth; | ||
|
||
/** | ||
* Create a new middleware instance. | ||
* | ||
* @param AuthManager $auth | ||
* @return void | ||
*/ | ||
public function __construct(AuthManager $auth) | ||
{ | ||
$this->auth = $auth; | ||
} | ||
|
||
/** | ||
* Handle an incoming request. | ||
* | ||
* @param \Illuminate\Http\Request $request | ||
* @param \Closure $next | ||
* @return mixed | ||
*/ | ||
public function handle($request, Closure $next) | ||
{ | ||
$this->authenticate($request); | ||
|
||
return $next($request); | ||
} | ||
|
||
/** | ||
* Handle authentication. | ||
* | ||
* @param \Illuminate\Http\Request $request | ||
* @return mixed | ||
*/ | ||
private function authenticate($request) | ||
{ | ||
if ($this->auth->check()) { | ||
return; | ||
} | ||
|
||
// Try Bearer authentication, with token in 'password' field on basic auth | ||
if (! $request->bearerToken()) { | ||
$password = $request->getPassword(); | ||
$request->headers->set('Authorization', 'Bearer '.$password); | ||
} | ||
|
||
$user = $this->auth->guard('api')->user($request); | ||
|
||
if ($user && (! $request->getUser() || $request->getUser() === $user->email)) { | ||
$this->auth->setUser($user); | ||
} else { | ||
// Basic authentication | ||
$this->auth->onceBasic(); | ||
} | ||
} | ||
} |
Oops, something went wrong.