login/pass: error messages below page title
[minimedit.git] / auth.inc.php
1 <?php
2 date_default_timezone_set('Europe/Amsterdam');
3
4 class User
5 {
6         public $dir, $login;
7
8         function __construct($dir = NULL, $existing = TRUE)
9         {
10                 if (empty($dir)) {
11                         return;
12                 }
13                 if (!file_exists($dir) and $existing) {
14                         throw new Exception("Gebruiker niet gevonden in $dir");
15                 }
16                 $this->dir = $dir;
17                 $this->login = preg_replace('{.*/}', '', $dir);
18         }
19
20         function __get($col)
21         {
22                 return $this->$col = $this->$col();  # run method and cache
23         }
24
25         function rawname()
26         {
27                 return rtrim(@file_get_contents("{$this->dir}/name.txt"));
28         }
29
30         function name()
31         {
32                 return htmlspecialchars(implode(' & ', explode("\n", $this->rawname)));
33         }
34
35         function html()
36         {
37                 $name = htmlspecialchars($this->login);
38                 if ($this->name and $this->name != $name) {
39                         $name = "{$this->name}<small> @$name</small>";
40                 }
41                 return $name;
42         }
43
44         function email()
45         {
46                 return rtrim(@file_get_contents("{$this->dir}/email.txt"));
47         }
48
49         function admin($permission = NULL)
50         {
51                 if (isset($permission)) {
52                         if (!$this->admin) {
53                                 return FALSE;  # empty results
54                         }
55                         preg_match_all('{[ /]}', $permission, $parts, PREG_OFFSET_CAPTURE);
56                         foreach ($parts[0] as $part) {
57                                 if (isset($this->admin[substr($permission, 0, $part[1])])) {
58                                         return TRUE;  # partial match
59                                 }
60                         }
61                         return isset($this->admin[$permission]);  # check level
62                 }
63                 if (!$this->dir or !@file_exists("{$this->dir}/.admin")) {
64                         return FALSE;  # not an admin
65                 }
66                 return array_fill_keys(explode("\n", file_get_contents("{$this->dir}/.admin")), TRUE);
67         }
68
69         function seen()
70         {
71                 return @filemtime("{$this->dir}/last.log");
72         }
73
74         function logclient()
75         {
76                 if ($log = @fopen("{$this->dir}/last.log", 'w')) {
77                         $line = $_SERVER['REMOTE_ADDR'].' '.$_SERVER['HTTP_USER_AGENT'];
78                         fwrite($log, $line."\n");
79                 }
80         }
81 }
82
83 function login_password_verify($input, $test)
84 {
85         if (substr($test, 0, 1) != '$') {
86                 # plaintext match for uncrypted passwords
87                 return $input === $test;
88         }
89         return password_verify($input, $test);
90 }
91
92 function login_setcookie()
93 {
94         global $User;
95         return setcookie('login', $User->auth, 0, '/');
96 }
97
98 function login($inuser, $inpass = NULL)
99 {
100         if (empty($inuser)) return;
101         if (!isset($inpass)) {
102                 @list ($inuser, $inauth) = explode(':', $inuser, 2);
103         }
104
105         # find password data by user name
106         $userdir = 'profile/'.preg_replace('/[^a-z0-9]+/', '-', strtolower($inuser));
107         $pwfile = "$userdir/.passwd";
108         if (!file_exists($pwfile)) return;
109         $usertest = trim(file_get_contents($pwfile));
110         if (!$usertest) return;
111
112         # verify password
113         $authhash = md5($usertest);
114         if (isset($inpass)) {
115                 if (!login_password_verify($inpass, $usertest)) return;
116         }
117         else {
118                 if ($inauth !== $authhash) return;
119         }
120
121         if (function_exists('apache_note')) apache_note('user', $inuser);
122
123         $user = new User($userdir);
124         $user->logclient();
125         $user->pass = $usertest;
126         $user->auth = "$inuser:$authhash";
127         return $user;
128 }
129
130 global $User;
131 if (isset($_COOKIE['login'])) {
132         $User = login($_COOKIE['login']);
133 }
134 if (!$User) {
135         $User = new User;
136 }
137