<?php
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class Certbot {
|
|
|
|
private $mc;
|
|
private $http;
|
|
|
|
public function index(Request $request, Response $response) {
|
|
session_start();
|
|
|
|
$state = mt_rand(10000,99999);
|
|
$_SESSION['state'] = $state;
|
|
|
|
$response->setContent(p3k\XRay\view('certbot', [
|
|
'title' => 'X-Ray',
|
|
'state' => $state
|
|
]));
|
|
return $response;
|
|
}
|
|
|
|
public function start_auth(Request $request, Response $response) {
|
|
session_start();
|
|
|
|
$_SESSION['client_id'] = $request->get('client_id');
|
|
$_SESSION['redirect_uri'] = $request->get('redirect_uri');
|
|
|
|
$query = http_build_query([
|
|
'me' => $request->get('me'),
|
|
'client_id' => $request->get('client_id'),
|
|
'redirect_uri' => $request->get('redirect_uri'),
|
|
'state' => $request->get('state'),
|
|
]);
|
|
|
|
$response->headers->set('Location', 'https://indieauth.com/auth?'.$query);
|
|
$response->setStatusCode(302);
|
|
return $response;
|
|
}
|
|
|
|
public function redirect(Request $request, Response $response) {
|
|
session_start();
|
|
|
|
$this->http = new p3k\HTTP();
|
|
|
|
if(!isset($_SESSION['state']) || $_SESSION['state'] != $request->get('state')) {
|
|
$response->headers->set('Location', '/cert?error=invalid_state');
|
|
$response->setStatusCode(302);
|
|
return $response;
|
|
}
|
|
|
|
if($code = $request->get('code')) {
|
|
|
|
$res = $this->http->post('https://indieauth.com/auth', http_build_query([
|
|
'code' => $code,
|
|
'client_id' => $_SESSION['client_id'],
|
|
'redirect_uri' => $_SESSION['redirect_uri'],
|
|
'state' => $_SESSION['state']
|
|
]), [
|
|
'Accept: application/json'
|
|
]);
|
|
$verify = json_decode($res['body'], true);
|
|
|
|
unset($_SESSION['state']);
|
|
|
|
if(isset($verify['me'])) {
|
|
|
|
if(in_array($verify['me'], Config::$admins)) {
|
|
$_SESSION['me'] = $verify['me'];
|
|
$response->headers->set('Location', '/cert');
|
|
} else {
|
|
$response->headers->set('Location', '/cert?error=invalid_user');
|
|
}
|
|
|
|
} else {
|
|
$response->headers->set('Location', '/cert?error=invalid');
|
|
}
|
|
|
|
} else {
|
|
$response->headers->set('Location', '/cert?error=missing_code');
|
|
}
|
|
|
|
$response->setStatusCode(302);
|
|
return $response;
|
|
}
|
|
|
|
public function save_challenge(Request $request, Response $response) {
|
|
session_start();
|
|
|
|
if(!isset($_SESSION['me']) || !in_array($_SESSION['me'], Config::$admins)) {
|
|
$response->headers->set('Location', '/cert?error=forbidden');
|
|
$response->setStatusCode(302);
|
|
return $response;
|
|
}
|
|
|
|
$token = $request->get('token');
|
|
$challenge = $request->get('challenge');
|
|
|
|
if(preg_match('/acme-challenge\/(.+)/', $token, $match)) {
|
|
$token = $match[1];
|
|
} elseif(!preg_match('/^[_a-zA-Z0-9]+$/', $token)) {
|
|
echo "Invalid token format\n";
|
|
die();
|
|
}
|
|
|
|
$this->_mc();
|
|
$this->mc->set('acme-challenge-'.$token, json_encode([
|
|
'token' => $token,
|
|
'challenge' => $challenge
|
|
]), 0, 600);
|
|
|
|
$response->setContent(p3k\XRay\view('certbot', [
|
|
'title' => 'X-Ray',
|
|
'challenge' => $challenge,
|
|
'token' => $token,
|
|
'verified' => true
|
|
]));
|
|
return $response;
|
|
}
|
|
|
|
public function logout(Request $request, Response $response) {
|
|
session_start();
|
|
unset($_SESSION['me']);
|
|
unset($_SESSION['client_id']);
|
|
unset($_SESSION['redirect_uri']);
|
|
unset($_SESSION['state']);
|
|
session_destroy();
|
|
$response->headers->set('Location', '/cert');
|
|
$response->setStatusCode(302);
|
|
return $response;
|
|
}
|
|
|
|
public function challenge(Request $request, Response $response, array $args) {
|
|
$this->_mc();
|
|
|
|
$token = $args['token'];
|
|
|
|
if($cache = $this->mc->get('acme-challenge-'.$token)) {
|
|
$acme = json_decode($cache, true);
|
|
|
|
$response->setContent($acme['challenge']);
|
|
} else {
|
|
$response->setStatusCode(404);
|
|
$response->setContent("Not Found\n");
|
|
}
|
|
|
|
$response->headers->set('Content-Type', 'text/plain');
|
|
return $response;
|
|
}
|
|
|
|
private function _mc() {
|
|
$this->mc = new Memcache();
|
|
$this->mc->addServer('127.0.0.1');
|
|
}
|
|
|
|
}
|