1<?php
2/**
3 * This class defines the abstract driver implementation for
4 * Horde_Core_Auth_Signup.
5 *
6 * Copyright 2002-2017 Horde LLC (http://www.horde.org/)
7 *
8 * See the enclosed file COPYING for license information (LGPL). If you did
9 * not receive this file, see http://opensource.org/licenses/lgpl-2.1.php
10 *
11 * @author   Marko Djukic <marko@oblo.com>
12 * @author   Michael Slusarz <slusarz@horde.org>
13 * @category Horde
14 * @license  http://opensource.org/licenses/lgpl-2.1.php LGPL
15 * @package  Core
16 */
17abstract class Horde_Core_Auth_Signup_Base
18{
19    /**
20     * Adds a new user to the system and handles any extra fields that may have
21     * been compiled, relying on the hooks.php file.
22     *
23     * @param mixed $info  Reference to array of parameters to be passed
24     *                     to hook.
25     *
26     * @throws Horde_Exception
27     */
28    public function addSignup(&$info)
29    {
30        /* @var $auth Horde_Auth_Base */
31        /* @var $injector Horde_Injector */
32        global $auth, $injector;
33
34        // Perform any preprocessing if requested.
35        $this->_preSignup($info);
36
37        // Attempt to add the user to the system.
38        $auth->addUser($info['user_name'], array('password' => $info['password']));
39
40        // Attempt to add/update any extra data handed in.
41        if (!empty($info['extra'])) {
42            try {
43                $injector->getInstance('Horde_Core_Hooks')->callHook(
44                    'signup_addextra',
45                    'horde',
46                    array(
47                        $info['user_name'],
48                        $info['extra'],
49                        $info['password']
50                    )
51                );
52            } catch (Horde_Exception_HookNotSet $e) {}
53        }
54    }
55
56    /**
57     * Queues the user's submitted registration info for later admin approval.
58     *
59     * @param mixed $info  Reference to array of parameters to be passed
60     *                     to hook.
61     *
62     * @throws Horde_Exception
63     * @throws Horde_Mime_Exception
64     */
65    public function queueSignup(&$info)
66    {
67        /* @var $conf array */
68        /* @var $injector Horde_Injector */
69        /* @var $registry Horde_Registry */
70        global $conf, $injector, $registry;
71
72        // Perform any preprocessing if requested.
73        $this->_preSignup($info);
74
75        // If it's a unique username, go ahead and queue the request.
76        $signup = $this->newSignup($info['user_name']);
77        if (!empty($info['extra'])) {
78            $signup->setData($info['extra']);
79        }
80        $signup->setData(array_merge($signup->getData(), array(
81            'dateReceived' => time(),
82            'password' => $info['password'],
83        )));
84
85        $this->_queueSignup($signup);
86
87        try {
88            $injector->getInstance('Horde_Core_Hooks')->callHook(
89                'signup_queued',
90                'horde',
91                array(
92                    $info['user_name'],
93                    $info
94                )
95            );
96        } catch (Horde_Exception_HookNotSet $e) {}
97
98        if (!empty($conf['signup']['email'])) {
99            $link = Horde::url($registry->get('webroot', 'horde') . '/admin/signup_confirm.php', true, -1)->setRaw(true)->add(array(
100                'u' => $signup->getName(),
101                'h' => hash_hmac('sha1', $signup->getName(), $conf['secret_key'])
102            ));
103            $message = sprintf(Horde_Core_Translation::t("A new account for the user \"%s\" has been requested through the signup form."), $signup->getName())
104                . "\n\n"
105                . Horde_Core_Translation::t("Approve the account:")
106                . "\n" . $link->copy()->add('a', 'approve') . "\n"
107                . Horde_Core_Translation::t("Deny the account:")
108                . "\n" . $link->copy()->add('a', 'deny');
109            $mail = new Horde_Mime_Mail(array(
110                'body' => $message,
111                'Subject' => sprintf(Horde_Core_Translation::t("Account signup request for \"%s\""), $signup->getName()),
112                'To' => $conf['signup']['email'],
113                'From' => $conf['signup']['email']));
114            $mail->send($injector->getInstance('Horde_Mail'));
115        }
116    }
117
118    /**
119     * Perform common presignup actions.
120     *
121     * @param array $info  Reference to array of parameters.
122     *
123     * @throws Horde_Exception
124     */
125    protected function _preSignup(&$info)
126    {
127        /* @var $auth Horde_Auth_Base */
128        /* @var $injector Horde_Injector */
129        global $auth, $injector;
130
131        try {
132            $info = $injector->getInstance('Horde_Core_Hooks')->callHook(
133                'signup_preprocess',
134                'horde',
135                array($info)
136            );
137        } catch (Horde_Exception_HookNotSet $e) {}
138
139        // Check to see if the username already exists in the auth backend or
140        // the signup queue.
141        if ($auth->exists($info['user_name']) ||
142            $this->exists($info['user_name'])) {
143            throw new Horde_Exception(sprintf(Horde_Core_Translation::t("Username \"%s\" already exists."), $info['user_name']));
144        }
145    }
146
147    /**
148     * Checks if a user exists in the system.
149     *
150     * @param string $user  The user to check.
151     *
152     * @return boolean  True if the user exists.
153     * @throws Horde_Db_Exception
154     */
155    abstract public function exists($user);
156
157    /**
158     * Queues the user's submitted registration info for later admin approval.
159     *
160     * @param object $signup  Signup data.
161     *
162     * @throws Horde_Exception
163     */
164    abstract protected function _queueSignup($signup);
165
166    /**
167     * Get a user's queued signup information.
168     *
169     * @param string $username  The username to retrieve the queued info for.
170     *
171     * @return object  The object for the requested signup.
172     * @throws Horde_Exception
173     */
174    abstract public function getQueuedSignup($username);
175
176    /**
177     * Get the queued information for all pending signups.
178     *
179     * @return array  An array of objects, one for each signup in the queue.
180     * @throws Horde_Exception
181     */
182    abstract public function getQueuedSignups();
183
184    /**
185     * Remove a queued signup.
186     *
187     * @param string $username  The user to remove from the signup queue.
188     *
189     * @throws Horde_Exception
190     */
191    abstract public function removeQueuedSignup($username);
192
193    /**
194     * Return a new signup object.
195     *
196     * @param string $name  The signups's name.
197     *
198     * @return object  A new signup object.
199     * @throws Horde_Exception
200     */
201    abstract public function newSignup($name);
202}
203