Issues (1965)

html/user/create_account.php (6 issues)

1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2008 University of California
5
//
6
// BOINC is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License
8
// as published by the Free Software Foundation,
9
// either version 3 of the License, or (at your option) any later version.
10
//
11
// BOINC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
// See the GNU Lesser General Public License for more details.
15
//
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19
// RPC handler for account creation
20
21
require_once("../inc/boinc_db.inc");
22
require_once("../inc/util.inc");
23
require_once("../inc/email.inc");
24
require_once("../inc/xml.inc");
25
require_once("../inc/user_util.inc");
26
require_once("../inc/team.inc");
27
require_once("../inc/password_compat/password.inc");
28
require_once("../inc/consent.inc");
29
30
xml_header();
31
32
$retval = db_init_xml();
33
if ($retval) xml_error($retval);
34
35
$config = get_config();
36
if (parse_bool($config, "disable_account_creation")) {
37
    xml_error(-1, "The project is not accepting new accounts.");
38
}
39
if (parse_bool($config, "disable_account_creation_rpc")) {
40
    if (parse_bool($config, "no_web_account_creation")) {
41
        xml_error(-1, "The project is not accepting new accounts.");
42
    } else {
43
        xml_error(-1, "Please visit the project web site to create an account, then try again.");
44
    }
45
}
46
47
if (defined('INVITE_CODES_RPC')) {
48
        $invite_code = get_str("invite_code");
49
        if (!preg_match(INVITE_CODES_RPC, $invite_code)) {
50
            xml_error(-1, "Invalid invitation code");
51
        }
52
} else {
53
    if (defined('INVITE_CODES')) {
54
        $invite_code = get_str("invite_code");
55
        if (!preg_match(INVITE_CODES, $invite_code)) {
56
            xml_error(-1, "Invalid invitation code");
57
        }
58
    }
59
}
60
61
$email_addr = get_str("email_addr");
62
$email_addr = strtolower($email_addr);
63
$passwd_hash = get_str("passwd_hash");
64
$user_name = get_str("user_name");
65
$team_name = get_str("team_name", true);
66
67
$consent_flag = get_str("consent_flag", true);
68
$source = get_str("source", true);
69
70
if (!is_valid_user_name($user_name, $reason)) {
71
    xml_error(ERR_BAD_USER_NAME, $reason);
72
}
73
74
if (!is_valid_email_syntax($email_addr)) {
75
    xml_error(ERR_BAD_EMAIL_ADDR);
76
}
77
if (!is_valid_email_sfs($email_addr)) {
78
    xml_error(ERR_BAD_EMAIL_ADDR, 'flagged by stopforumspam.com');
79
}
80
if (is_banned_email_addr($email_addr)) {
81
    xml_error(ERR_BAD_EMAIL_ADDR);
82
}
83
84
if (strlen($passwd_hash) != 32) {
85
    xml_error(-1, "password hash length not 32");
86
}
87
88
$tmpuser = BoincUser::lookup_prev_email_addr($email_addr);
89
if ($tmpuser) {
90
    xml_error(ERR_DB_NOT_UNIQUE);
91
}
92
93
$user = BoincUser::lookup_email_addr($email_addr);
94
if ($user) {
95
    if ($user->passwd_hash != $passwd_hash && !password_verify($passwd_hash, $user->passwd_hash)) {
96
        xml_error(ERR_DB_NOT_UNIQUE);
97
    } else {
98
        $authenticator = $user->authenticator;
99
    }
100
} else {
101
    // Get consent type setting
102
    list($checkct, $ctid) = check_consent_type(CONSENT_TYPE_ENROLL);
103
104
    // Projects can require explicit consent for account creation
105
    // by setting "account_creation_rpc_require_consent" to 1 in
106
    // config.xml
107
    //
108
    if (parse_bool($config, "account_creation_rpc_require_consent")) {
109
        // Consistency checks
110
        //
111
        if (!check_termsofuse()) {
112
            error_log("Project configuration error! " .
0 ignored issues
show
The use of function error_log() is discouraged
Loading history...
113
                "Terms of use undefined while 'account_creation_rpc_require_consent' enabled!"
114
            );
115
        }
116
        if (!$checkct) {
117
            error_log("Project configuration error! " .
0 ignored issues
show
The use of function error_log() is discouraged
Loading history...
118
              "'CONSENT_TYPE_ENROLL' disabled while 'account_creation_rpc_require_consent' enabled!"
119
            );
120
        }
121
122
        // Check consent requirement
123
        //
124
        if (is_null($consent_flag) or !$source) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
125
            xml_error(ERR_ACCT_REQUIRE_CONSENT,
126
                "This project requires you to consent to its terms of use. " .
127
                "Please update your BOINC software " .
128
                "or register via the project's website " .
129
                "or contact your account manager's provider."
130
            );
131
        }
132
    }
133
134
    // Create user account
135
    //
136
    $user = make_user($email_addr, $user_name, $passwd_hash, 'International');
137
    if (!$user) {
138
        xml_error(ERR_DB_NOT_UNIQUE);
139
    }
140
141
142
    if (defined('INVITE_CODES_RPC')) {
143
        // record the invite code
144
        //
145
        $r = BoincDb::escape_string($invite_code);
146
        $user->update("signature='$r'");
147
    } else if (defined('INVITE_CODES')) {
148
        error_log("Account for '$email_addr' created using invitation code '$invite_code'");
0 ignored issues
show
The use of function error_log() is discouraged
Loading history...
149
    }
150
151
    // If the project is configured to use the CONSENT_TYPE_ENROLL, record it.
152
    //
153
    if ($checkct and check_termsofuse()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
154
        // As of Sept 2018, this code allows 'legacy' boinc clients to
155
        // create accounts. If consent_flag is null the code creates
156
        // an account as normal and there is no update to the consent
157
        // DB table.
158
        //
159
        // Logic:
160
        // * An old(er) BOINC Manager or third party GUI that doesn't
161
        // * support the new consent features.
162
        //   -> consent_flag not set (NULL).
163
        // * A new(er) BOINC GUI, the terms of use are shown and user
164
        // * agrees.
165
        //   -> consent_flag=1
166
        // * A new or older GUI, terms of use shown but the user not
167
        // * not agree.
168
        //   -> no create account RPC at all
169
        //
170
        if ( (!is_null($consent_flag)) and $source) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
171
            // Record the user giving consent in database - if consent_flag is 0,
172
            // this is an 'anonymous account' and consent_not_required is
173
            // set to 1.
174
            if ($consent_flag==0) {
175
                $rc = consent_to_a_policy($user, $ctid, 0, 1, $source);
176
            } else  {
177
                $rc = consent_to_a_policy($user, $ctid, 1, 0, $source);
178
            }
179
            if (!$rc) {
180
                xml_error(-1, "database error, please contact site administrators");
181
            }
182
        }
183
    }
184
}
185
186
if ($team_name) {
187
    $team_name = BoincDb::escape_string($team_name);
188
    $team = BoincTeam::lookup("name='$team_name'");
189
    if ($team && $team->joinable) {
190
        user_join_team($team, $user);
191
    }
192
}
193
194
echo " <account_out>\n";
195
echo "   <authenticator>$user->authenticator</authenticator>\n";
196
echo "</account_out>\n";
197
198
?>
199