PhabricatorPeopleNewController.php 7.56 KB
Newer Older
epriestley's avatar
epriestley committed
1
2
<?php

3
final class PhabricatorPeopleNewController
4
  extends PhabricatorPeopleController {
epriestley's avatar
epriestley committed
5

6
7
  public function handleRequest(AphrontRequest $request) {
    $type = $request->getURIData('type');
8
    $admin = $request->getUser();
9

10
11
12
13
14
    id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
      $admin,
      $request,
      $this->getApplicationURI());

epriestley's avatar
epriestley committed
15
16
    $is_bot = false;
    $is_list = false;
17
    switch ($type) {
18
      case 'standard':
19
20
        $this->requireApplicationCapability(
          PeopleCreateUsersCapability::CAPABILITY);
21
22
23
24
        break;
      case 'bot':
        $is_bot = true;
        break;
epriestley's avatar
epriestley committed
25
26
27
      case 'list':
        $is_list = true;
        break;
28
29
      default:
        return new Aphront404Response();
30
31
    }

32
    $user = new PhabricatorUser();
33
    $require_real_name = PhabricatorEnv::getEnvConfig('user.require-real-name');
34

epriestley's avatar
epriestley committed
35
    $e_username = true;
36
    $e_realname = $require_real_name ? true : null;
epriestley's avatar
epriestley committed
37
38
39
    $e_email    = true;
    $errors = array();

40
41
    $welcome_checked = true;

42
43
    $new_email = null;

epriestley's avatar
epriestley committed
44
    if ($request->isFormPost()) {
45
46
      $welcome_checked = $request->getInt('welcome');

47
48
49
50
51
52
      $user->setUsername($request->getStr('username'));

      $new_email = $request->getStr('email');
      if (!strlen($new_email)) {
        $errors[] = pht('Email is required.');
        $e_email = pht('Required');
53
54
      } else if (!PhabricatorUserEmail::isValidAddress($new_email)) {
        $errors[] = PhabricatorUserEmail::describeValidAddresses();
55
        $e_email = pht('Invalid');
56
      } else if (!PhabricatorUserEmail::isAllowedAddress($new_email)) {
57
        $errors[] = PhabricatorUserEmail::describeAllowedAddresses();
58
        $e_email = pht('Not Allowed');
59
60
      } else {
        $e_email = null;
epriestley's avatar
epriestley committed
61
      }
62

epriestley's avatar
epriestley committed
63
64
65
      $user->setRealName($request->getStr('realname'));

      if (!strlen($user->getUsername())) {
66
        $errors[] = pht('Username is required.');
Chad Little's avatar
Chad Little committed
67
        $e_username = pht('Required');
68
      } else if (!PhabricatorUser::validateUsername($user->getUsername())) {
69
        $errors[] = PhabricatorUser::describeValidUsername();
Chad Little's avatar
Chad Little committed
70
        $e_username = pht('Invalid');
71
72
      } else {
        $e_username = null;
epriestley's avatar
epriestley committed
73
74
      }

75
      if (!strlen($user->getRealName()) && $require_real_name) {
Chad Little's avatar
Chad Little committed
76
77
        $errors[] = pht('Real name is required.');
        $e_realname = pht('Required');
78
79
      } else {
        $e_realname = null;
epriestley's avatar
epriestley committed
80
81
82
      }

      if (!$errors) {
83
        try {
84

85
86
87
88
89
90
          $email = id(new PhabricatorUserEmail())
            ->setAddress($new_email)
            ->setIsVerified(0);

          // Automatically approve the user, since an admin is creating them.
          $user->setIsApproved(1);
91

epriestley's avatar
epriestley committed
92
93
          // If the user is a bot or list, approve their email too.
          if ($is_bot || $is_list) {
94
95
96
            $email->setIsVerified(1);
          }

97
98
99
          id(new PhabricatorUserEditor())
            ->setActor($admin)
            ->createNewUser($user, $email);
epriestley's avatar
epriestley committed
100

101
          if ($is_bot) {
epriestley's avatar
epriestley committed
102
103
            id(new PhabricatorUserEditor())
              ->setActor($admin)
104
              ->makeSystemAgentUser($user, true);
105
          }
106

epriestley's avatar
epriestley committed
107
108
109
110
111
112
          if ($is_list) {
            id(new PhabricatorUserEditor())
              ->setActor($admin)
              ->makeMailingListUser($user, true);
          }

113
114
115
116
117
118
119
          if ($welcome_checked) {
            $welcome_engine = id(new PhabricatorPeopleWelcomeMailEngine())
              ->setSender($admin)
              ->setRecipient($user);
            if ($welcome_engine->canSendMail()) {
              $welcome_engine->sendMail();
            }
120
          }
121

122
          $response = id(new AphrontRedirectResponse())
123
            ->setURI('/p/'.$user->getUsername().'/');
124
          return $response;
125
        } catch (AphrontDuplicateKeyQueryException $ex) {
Chad Little's avatar
Chad Little committed
126
          $errors[] = pht('Username and email must be unique.');
127
128
129

          $same_username = id(new PhabricatorUser())
            ->loadOneWhere('username = %s', $user->getUsername());
130
131
          $same_email = id(new PhabricatorUserEmail())
            ->loadOneWhere('address = %s', $new_email);
132
133

          if ($same_username) {
Chad Little's avatar
Chad Little committed
134
            $e_username = pht('Duplicate');
135
136
137
          }

          if ($same_email) {
Chad Little's avatar
Chad Little committed
138
            $e_email = pht('Duplicate');
139
140
          }
        }
epriestley's avatar
epriestley committed
141
142
143
      }
    }

144
145
146
147
    $form = id(new AphrontFormView())
      ->setUser($admin);

    if ($is_bot) {
Chad Little's avatar
Chad Little committed
148
      $title = pht('Create New Bot');
149
      $form->appendRemarkupInstructions(
epriestley's avatar
epriestley committed
150
151
        pht('You are creating a new **bot** user account.'));
    } else if ($is_list) {
Chad Little's avatar
Chad Little committed
152
      $title = pht('Create New Mailing List');
epriestley's avatar
epriestley committed
153
154
      $form->appendRemarkupInstructions(
        pht('You are creating a new **mailing list** user account.'));
155
    } else {
Chad Little's avatar
Chad Little committed
156
      $title = pht('Create New User');
157
      $form->appendRemarkupInstructions(
Joshua Spence's avatar
Joshua Spence committed
158
        pht('You are creating a new **standard** user account.'));
159
    }
epriestley's avatar
epriestley committed
160
161
162
163

    $form
      ->appendChild(
        id(new AphrontFormTextControl())
Chad Little's avatar
Chad Little committed
164
          ->setLabel(pht('Username'))
epriestley's avatar
epriestley committed
165
166
          ->setName('username')
          ->setValue($user->getUsername())
167
          ->setError($e_username))
epriestley's avatar
epriestley committed
168
169
      ->appendChild(
        id(new AphrontFormTextControl())
Chad Little's avatar
Chad Little committed
170
          ->setLabel(pht('Real Name'))
epriestley's avatar
epriestley committed
171
172
          ->setName('realname')
          ->setValue($user->getRealName())
173
          ->setError($e_realname))
174
      ->appendChild(
175
176
177
178
179
180
181
        id(new AphrontFormTextControl())
          ->setLabel(pht('Email'))
          ->setName('email')
          ->setValue($new_email)
          ->setCaption(PhabricatorUserEmail::describeAllowedAddresses())
          ->setError($e_email));

epriestley's avatar
epriestley committed
182
    if (!$is_bot && !$is_list) {
183
      $form->appendChild(
184
185
186
187
        id(new AphrontFormCheckboxControl())
          ->addCheckbox(
            'welcome',
            1,
188
            pht('Send "Welcome to Phabricator" email with login instructions.'),
189
            $welcome_checked));
190
    }
191
192

    $form
epriestley's avatar
epriestley committed
193
194
      ->appendChild(
        id(new AphrontFormSubmitControl())
195
          ->addCancelButton($this->getApplicationURI())
196
197
198
199
200
201
202
          ->setValue(pht('Create User')));

    if ($is_bot) {
      $form
        ->appendChild(id(new AphrontFormDividerControl()))
        ->appendRemarkupInstructions(
          pht(
epriestley's avatar
epriestley committed
203
            '**Why do bot accounts need an email address?**'.
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
            "\n\n".
            'Although bots do not normally receive email from Phabricator, '.
            'they can interact with other systems which require an email '.
            'address. Examples include:'.
            "\n\n".
            "  - If the account takes actions which //send// email, we need ".
            "    an address to use in the //From// header.\n".
            "  - If the account creates commits, Git and Mercurial require ".
            "    an email address for authorship.\n".
            "  - If you send email //to// Phabricator on behalf of the ".
            "    account, the address can identify the sender.\n".
            "  - Some internal authentication functions depend on accounts ".
            "    having an email address.\n".
            "\n\n".
            "The address will automatically be verified, so you do not need ".
            "to be able to receive mail at this address, and can enter some ".
            "invalid or nonexistent (but correctly formatted) address like ".
            "`bot@yourcompany.com` if you prefer."));
    }

Chad Little's avatar
Chad Little committed
224
    $box = id(new PHUIObjectBoxView())
Chad Little's avatar
Chad Little committed
225
      ->setHeaderText($title)
226
      ->setFormErrors($errors)
Chad Little's avatar
Chad Little committed
227
      ->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
Chad Little's avatar
Chad Little committed
228
229
      ->setForm($form);

230
231
    $crumbs = $this->buildApplicationCrumbs();
    $crumbs->addTextCrumb($title);
Chad Little's avatar
Chad Little committed
232
    $crumbs->setBorder(true);
233

Chad Little's avatar
Chad Little committed
234
235
236
237
238
239
240
    $view = id(new PHUITwoColumnView())
      ->setFooter($box);

    return $this->newPage()
      ->setTitle($title)
      ->setCrumbs($crumbs)
      ->appendChild($view);
241
242
  }

epriestley's avatar
epriestley committed
243
}