<?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');
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								}
							 |