1<?php
2    /**
3     * Example Action Plugin:   Example Component.
4     *
5     * @author     Stefan Agner <falstaff@deheime.ch>
6     */
7
8    if(!defined('DOKU_INC')) die();
9    if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
10    require_once DOKU_PLUGIN.'action.php';
11
12    class action_plugin_zenlogin extends DokuWiki_Action_Plugin {
13        var $cookie_name;
14        var $zp_path;
15        var $zp_mysql_user;
16        var $zp_mysql_pass;
17        var $zp_mysql_host;
18        var $zp_mysql_database;
19        var $zp_mysql_prefix;
20        var $zp_userpass_hash; // This hash value could be found on zenphoto admin/options/general tab
21        var $zp_rights;
22
23        function action_plugin_zenlogin() {
24            $this->cookie_name = 'zp_user_auth';
25            $this->zp_path = $this->getConf('zenphoto_path');
26            $this->zp_mysql_user = $this->getConf('mysql_user');
27            $this->zp_mysql_pass = $this->getConf('mysql_password');
28            $this->zp_mysql_host = $this->getConf('mysql_host');
29            $this->zp_mysql_database = $this->getConf('mysql_database');
30            $this->zp_mysql_prefix = $this->getConf('mysql_prefix');
31            $this->zp_userpass_hash = $this->getConf('user_password_hash');
32            $rights = split(",", $this->getConf('zenphoto_permissions'));
33            $right_numeric = 0;
34            foreach($rights as $right)
35            {
36                if($right == "overview_rights") $right_numeric += 2^2;
37                else if($right == "view_all_rights") $right_numeric += 2^4;
38                else if($right == "upload_rights") $right_numeric += 2^6;
39                else if($right == "post_comment_rights") $right_numeric += 2^8;
40                else if($right == "comment_rights") $right_numeric += 2^10;
41                else if($right == "album_rights") $right_numeric += 2^12;
42                else if($right == "zenpage_pages_rights") $right_numeric += 2^14;
43                else if($right == "zenpage_news_rights") $right_numeric += 2^16;
44                else if($right == "files_rights") $right_numeric += 2^18;
45                else if($right == "manage_all_pages_rights") $right_numeric += 2^20;
46                else if($right == "manage_all_news_rights") $right_numeric += 2^22;
47                else if($right == "manage_all_album_rights") $right_numeric += 2^24;
48                else if($right == "themes_rights") $right_numeric += 2^26;
49                else if($right == "tags_rights") $right_numeric += 2^28;
50                else if($right == "options_rights") $right_numeric += 2^29;
51                else if($right == "admin_rights") $right_numeric += 2^30;
52            }
53            $this->zp_rights = $right_numeric;
54        }
55
56
57        /**
58         * Register its handlers with the DokuWiki's event controller
59         */
60        function register(&$controller) {
61
62            $controller->register_hook('AUTH_LOGIN_CHECK', 'BEFORE', $this,
63                                       'event_login');
64            $controller->register_hook('AUTH_USER_CHANGE', 'AFTER', $this,
65                                       'event_userchange');
66            $controller->register_hook('ACTION_HEADERS_SEND', 'BEFORE', $this,
67                                       'event_headers_send');
68
69
70        }
71
72        /**
73         * Calculates password hash the zenphoto way
74         *
75         * @author Stefan Agner <stefan@agner.ch>
76         */
77        function zenphoto_hashpw($user, $password) {
78            return md5($user.$password.$this->zp_userpass_hash);
79        }
80
81        /**
82         * Set cookie to login zenphoto as well
83         *
84         * @author Stefan Agner <stefan@agner.ch>
85         */
86        function zenphoto_login($user, $password, $sticky=true) {
87            if($this->getConf('single_sign_on'))
88            {
89                $con = mysql_connect($this->zp_mysql_host,$this->zp_mysql_user,$this->zp_mysql_pass);
90                if (!$con)
91                    die('Could not connect: ' . mysql_error());
92
93                mysql_select_db($this->zp_mysql_database, $con);
94
95                $query = sprintf("SELECT id FROM ".$this->zp_mysql_prefix."administrators WHERE user = '%s'",
96                                 mysql_real_escape_string($user));
97                $result = mysql_query($query, $con);
98                $row = mysql_fetch_object($result);
99
100                $pwhash = $this->zenphoto_hashpw($user, $password);
101		// The Cookie format nowadays is $pwhash . '.' . $user, but this still works. Saves a SQL roundtrip
102                if($sticky)
103                    setcookie($this->cookie_name, $pwhash . '.' . $row->id, time()+(60*60*24*365), $this->zp_path); // 1 year, Dokuwiki default
104                else
105                    setcookie($this->cookie_name, $pwhash . '.' . $row->id, null, $this->zp_path); // browser close
106            }
107        }
108
109        /**
110         * Set cookie to logout zenphoto as well
111         *
112         * @author Stefan Agner <stefan@agner.ch>
113         */
114        function zenphoto_logout() {
115            if($this->getConf('single_sign_on'))
116              setcookie($this->cookie_name, '', time()-31536000, $this->zp_path);
117        }
118
119        /**
120         * Check if user is still logged in just before headers are sent (to be able to delete the cookie)
121         *
122         * @author Stefan Agner <stefan@agner.ch>
123         */
124        function event_headers_send(&$event, $param) {
125            // No userlogin, might be a logout
126            if($_SERVER['REMOTE_USER'] == "")
127                $this->zenphoto_logout();
128        }
129
130
131        /**
132         * Set cookie to login zenphoto as well
133         *
134         * @author Stefan Agner <stefan@agner.ch>
135         */
136        function event_login(&$event, $param) {
137            // Check if user is set (this is only the case if we just pressed login, while the session is running the event happens but no user is set)
138            if($event->data['user'] != "")
139                $this->zenphoto_login($event->data['user'], $event->data['password'], $event->data['sticky'] == 1);
140
141        }
142
143        /**
144         * Update user information in zenphoto as well
145         *
146         * @author Stefan Agner <stefan@agner.ch>
147         */
148        function event_userchange(&$event, $param) {
149            // Connect to zenphoto database...
150            $con = mysql_connect($this->zp_mysql_host,$this->zp_mysql_user,$this->zp_mysql_pass);
151            if (!$con)
152            {
153                die('Could not connect: ' . mysql_error());
154            }
155
156            mysql_select_db($this->zp_mysql_database, $con);
157
158            if($event->data['type'] == 'create' && $event->data['modification_result'])
159            {
160                $user = mysql_real_escape_string($event->data['params'][0]);
161                $pass = $this->zenphoto_hashpw($user, $event->data['params'][1]);
162                $name = mysql_real_escape_string($event->data['params'][2]);
163                $email = mysql_real_escape_string($event->data['params'][3]);
164                $custom_data = "User generated by DokuWiki zenlogin Plug-In.";
165                mysql_query("INSERT INTO ".$this->zp_mysql_prefix."administrators (user, pass, name, email, rights, valid, custom_data) ".
166                            "VALUES ('".$user."', '".$pass."', '".$name."', '".$email."', ".$this->zp_rights.", 1, '".$custom_data."')", $con);
167            }
168            else if($event->data['type'] == 'modify' && $event->data['modification_result'])
169            {
170                // params is an array, [0] ==> Username, [1] ==> Fields
171                $user = mysql_real_escape_string($event->data['params'][0]);
172                if(isset($event->data['params'][1]["name"]))
173                {
174                    $name = $event->data['params'][1]["name"];
175                    mysql_query("UPDATE ".$this->zp_mysql_prefix."administrators SET name = '".$name."' WHERE user = '".$user."'", $con);
176                }
177
178                if(isset($event->data['params'][1]["mail"]))
179                {
180                    $email = $event->data['params'][1]["mail"];
181                    mysql_query("UPDATE ".$this->zp_mysql_prefix."administrators SET email = '".$email."' WHERE user = '".$user."'", $con);
182                }
183
184                if(isset($event->data['params'][1]["pass"]))
185                {
186                    // Change the password with new hash
187                    $pass = $this->zenphoto_hashpw($user, $event->data['params'][1]["pass"]);
188                    mysql_query("UPDATE ".$this->zp_mysql_prefix."administrators SET pass = '".$pass."' WHERE user = '".$user."'", $con);
189
190                    // Also change the cookie for zenphoto
191                    $this->zenphoto_login($user, $event->data['params'][1]["pass"]);
192                }
193            }
194            else if($event->data['type'] == 'delete' && $event->data['modification_result'] > 0)
195            {
196                // params is an array, [0] ==> List of users to delete (array)
197
198                // Modification result contains number of deleted users
199                for($i = 0; $i < $event->data['modification_result'];$i++)
200                {
201                    $user = mysql_real_escape_string($event->data['params'][0][$i]);
202                    mysql_query("DELETE FROM ".$this->zp_mysql_prefix."administrators WHERE user = '".$user."'", $con);
203                }
204            }
205            mysql_close($con);
206
207        }
208
209
210    }
211
212
213