remove auto_increment from sql dump
[anoweco.git] / www / auth.php
1 <?php
2 namespace anoweco;
3 /**
4  * IndieAuth endpoint
5  *
6  * @author Christian Weiske <cweiske@cweiske.de>
7  */
8 header('HTTP/1.0 500 Internal Server Error');
9 require 'www-header.php';
10
11 function getOrCreateUser($mode, $name, $email)
12 {
13     if ($mode == 'anonymous') {
14         $name  = 'Anonymous';
15         $email = '';
16     } else {
17         if ($name == '') {
18             $name = 'Anonymous';
19         }
20     }
21     $imageurl = getImageUrl($email);
22
23     $storage = new Storage();
24     $id = $storage->findUser($name, $imageurl);
25     if ($id !== null) {
26         return $id;
27     }
28     $id = $storage->createUser($name, $imageurl);
29     return $id;
30 }
31
32 function getImageUrl($email)
33 {
34     //FIXME: libravatar
35     return Urls::userImg((object)['user_imageurl' => '']);
36 }
37
38 header('IndieAuth: authorization_endpoint');
39 if ($_SERVER['REQUEST_METHOD'] == 'GET') {
40     if (count($_GET) == 0) {
41         //no parameters - show the index page
42         header('HTTP/1.0 200 OK');
43         header('Content-Type: text/html');
44         render('auth-index', ['baseurl' => Urls::full('/')]);
45         exit();
46     }
47
48     $me            = verifyUrlParameter($_GET, 'me');
49     $redirect_uri  = verifyUrlParameter($_GET, 'redirect_uri');
50     $client_id     = verifyUrlParameter($_GET, 'client_id');
51     $state         = getOptionalParameter($_GET, 'state', null);
52     $response_type = getOptionalParameter($_GET, 'response_type', 'id');
53     $scope         = getOptionalParameter($_GET, 'scope', null);
54
55     //FIXME: if $me is an actual user, load his data
56
57     //let the user choose his identity
58     header('HTTP/1.0 200 OK');
59     render(
60         'auth-choose',
61         array(
62             'auth' => array(
63                 'redirect_uri'  => $redirect_uri,
64                 'client_id'     => $client_id,
65                 'state'         => $state,
66                 'response_type' => $response_type,
67                 'scope'         => $scope,
68             ),
69             'formaction' => '/auth.php?action=login',
70         )
71     );
72     exit();
73 } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
74     if (isset($_GET['action']) && $_GET['action'] == 'login') {
75         //log the user in
76         $auth = $_POST['auth'];
77         $redirect_uri  = verifyUrlParameter($auth, 'redirect_uri');
78         $client_id     = verifyUrlParameter($auth, 'client_id');
79         $state         = getOptionalParameter($auth, 'state', null);
80         $response_type = getOptionalParameter($auth, 'response_type', 'id');
81         $scope         = getOptionalParameter($auth, 'scope', null);
82
83         $id = $_POST['id'];
84         verifyParameter($id, 'mode');
85
86         $userId = getOrCreateUser(
87             $id['mode'], trim($id['name']), trim($id['email'])
88         );
89         $me = Urls::full(Urls::user($userId));
90
91         $code = base64_encode(
92             http_build_query(
93                 [
94                     'emoji'     => '\360\237\222\251',
95                     'me'        => $me,
96                     'scope'     => $scope,
97                     'signature' => 'FIXME',
98                 ]
99             )
100         );
101
102         //redirect back to client
103         $url = new \Net_URL2($redirect_uri);
104         $url->setQueryVariable('code', $code);
105         $url->setQueryVariable('me', $me);
106         $url->setQueryVariable('state', $state);
107         header('Location: ' . $url->getURL());
108         exit();
109     } else {
110         //auth code verification
111         $code         = base64_decode(verifyParameter($_POST, 'code'));
112         $redirect_uri = verifyUrlParameter($_POST, 'redirect_uri');
113         $client_id    = verifyUrlParameter($_POST, 'client_id');
114         $state        = getOptionalParameter($_POST, 'state', null);
115
116         parse_str($code, $codeParts);
117         $emoji     = verifyParameter($codeParts, 'emoji');
118         $signature = verifyParameter($codeParts, 'signature');
119         $me        = verifyUrlParameter($codeParts, 'me');
120         if ($emoji != '\360\237\222\251') {
121             error('Dog poo missing');
122         }
123         if ($signature != 'FIXME') {
124             error('Invalid signature');
125         }
126         header('HTTP/1.0 200 OK');
127         header('Content-type: application/x-www-form-urlencoded');
128         echo http_build_query(['me' => $me]);
129         exit();
130     }
131 } else if ($_SERVER['REQUEST_METHOD'] == 'HEAD') {
132     //indieauth.com makes a HEAD request at first
133     header('HTTP/1.0 200 OK');
134     exit();
135 } else {
136     error('Unsupported HTTP request method');
137 }
138 ?>