Skip to content

Commit

Permalink
$Opt["disableNewUsers"] can be set to "other".
Browse files Browse the repository at this point in the history
Which prevents any real user from creating other accounts (because
on the test site, account creation was abused).
  • Loading branch information
kohler committed Oct 4, 2023
1 parent add407c commit cdb6dd6
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 36 deletions.
1 change: 1 addition & 0 deletions etc/distoptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
// defaultEmailDomain Set to the default domain for account email addresses
// when using httpAuthLogin.
// disableNewUsers Don’t allow new users to register.
// disableNonPC Disable all accounts except PC and sysadmin accounts.


// PASSWORD SECURITY
Expand Down
2 changes: 1 addition & 1 deletion lib/mailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ function expand($text, $field = null) {
}

// lose newlines on header expansion
if ($this->context != self::CONTEXT_BODY) {
if ($this->context !== self::CONTEXT_BODY) {
$text = rtrim(preg_replace('/[\r\n\f\x0B]+/', ' ', $text));
}

Expand Down
14 changes: 11 additions & 3 deletions src/conference.php
Original file line number Diff line number Diff line change
Expand Up @@ -1863,9 +1863,17 @@ function external_login() {

/** @return bool */
function allow_user_self_register() {
return !$this->external_login()
&& !$this->disable_non_pc
&& !$this->opt("disableNewUsers");
if ($this->external_login() || $this->disable_non_pc) {
return false;
}
$dnu = $this->opt("disableNewUsers");
return !$dnu || $dnu === "other";
}

/** @return bool */
function allow_user_activate_other() {
$dnu = $this->opt("disableNewUsers");
return !$dnu || $dnu === true || $dnu === "self";
}


Expand Down
49 changes: 31 additions & 18 deletions src/contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -262,29 +262,39 @@ private function __construct($conf) {
/** @return Contact */
static function make(Conf $conf) {
$u = new Contact($conf);
$u->set_roles_properties();
$u->contactXid = self::$next_xid--;
$u->set_roles_properties();
return $u;
}

/** @param ?string $email
* @return Contact */
static function make_email(Conf $conf, $email) {
$u = new Contact($conf);
$u->contactXid = self::$next_xid--;
$u->email = $email ?? "";
$u->set_roles_properties();
return $u;
}

/** @param int $contactId
* @return Contact */
static function make_placeholder(Conf $conf) {
$u = new Contact($conf);
$u->contactXid = self::$next_xid--;
$u->disabled = self::DISABLEMENT_PLACEHOLDER;
$u->set_roles_properties();
return $u;
}

/** @param int $contactId
* @return Contact */
static function make_placeholder(Conf $conf, $contactId) {
static function make_deleted(Conf $conf, $contactId) {
$u = new Contact($conf);
$u->contactId = $contactId;
$u->contactXid = $contactId > 0 ? $contactId : self::$next_xid--;
$u->email = "unknown";
$u->disablement = self::DISABLEMENT_USER;
$u->email = "<deleted>";
$u->disablement = self::DISABLEMENT_DELETED;
$u->set_roles_properties();
return $u;
}
Expand All @@ -293,10 +303,10 @@ static function make_placeholder(Conf $conf, $contactId) {
* @return Contact */
static function make_cdb_email(Conf $conf, $email) {
$u = new Contact($conf);
$u->contactXid = self::$next_xid--;
$u->email = $email ?? "";
$u->cdb_confid = $conf->cdb_confid();
$u->set_roles_properties();
$u->contactXid = self::$next_xid--;
return $u;
}

Expand All @@ -307,6 +317,7 @@ static function make_keyed(Conf $conf, $args) {
// the importable properties
$u = new Contact($conf);
$u->contactId = $args["contactId"] ?? 0;
$u->contactXid = $u->contactId > 0 ? $u->contactId : self::$next_xid--;
$u->email = trim($args["email"] ?? "");
$u->firstName = $args["firstName"] ?? $args["first"] ?? "";
$u->lastName = $args["lastName"] ?? $args["last"] ?? "";
Expand All @@ -317,22 +328,21 @@ static function make_keyed(Conf $conf, $args) {
$u->disablement = $args["disablement"] ?? 0;
$u->disabled = $u->disablement & self::DISABLEMENT_DB;
$u->set_roles_properties();
$u->contactXid = $u->contactId ? : self::$next_xid--;
return $u;
}

/** @param array{email?:string,firstName?:string,lastName?:string} $args
* @return Contact */
static function make_site_contact(Conf $conf, $args) {
$u = new Contact($conf);
$u->contactXid = self::$next_xid--;
$u->email = $args["email"] ?? "";
$u->firstName = $args["firstName"] ?? "";
$u->lastName = $args["lastName"] ?? "";
$u->roles = self::ROLE_PC | self::ROLE_CHAIR;
$u->_root_user = true;
$u->_dangerous_track_mask = 0;
$u->set_roles_properties();
$u->contactXid = self::$next_xid--;
return $u;
}

Expand Down Expand Up @@ -1964,20 +1974,23 @@ function import_prop($src, $ifempty) {
$this->set_prop($prop, $src->prop1($prop, $shape), $ifempty);
}

// disablement requires special handling
if ($this->cdb_confid !== 0
&& $this->contactDbId === 0
&& $src->disablement !== 0) {
// creating a cdb user for a disabled local user: cdb is placeholder
// disablement import is special
// source is disabled local user, creating cdb user: cdb is placeholder
if ($src->disablement !== 0
&& $this->cdb_confid !== 0
&& $this->contactDbId === 0) {
$this->set_prop("disabled", $this->disabled | self::DISABLEMENT_PLACEHOLDER);
} else if (($this->disabled & self::DISABLEMENT_PLACEHOLDER) !== 0
&& $src->disablement === 0) {
// saving a non-placeholder user: other user loses placeholder status
}
// source is non-disabled local user: this is not placeholder
if ($src->cdb_confid === 0
&& $src->disablement === 0
&& ($this->disabled & self::DISABLEMENT_PLACEHOLDER) !== 0) {
$this->set_prop("disabled", $this->disabled & ~self::DISABLEMENT_PLACEHOLDER);
}
if ($src->cdb_confid !== 0
&& ($src->disabled & self::DISABLEMENT_USER) !== 0) {
// globally disabled users are locally disabled too
// source is globally disabled: this local user is disabled
if (($src->disabled & self::DISABLEMENT_USER) !== 0
&& $src->cdb_confid !== 0
&& $this->cdb_confid === 0) {
$this->set_prop("disabled", $this->disabled | self::DISABLEMENT_USER);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/logentry.php
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ private function _make_users() {
}
if (!empty($this->need_users)) {
foreach ($this->need_users as $cid => $x) {
$this->users[$cid] = Contact::make_keyed($this->conf, ["contactId" => $cid, "disablement" => Contact::DISABLEMENT_DELETED]);
$this->users[$cid] = Contact::make_deleted($this->conf, $cid);
}
$result = $this->conf->qe("select " . $this->conf->deleted_user_query_fields() . " from DeletedContactInfo where contactId?a", array_keys($this->need_users));
while (($user = Contact::fetch($result, $this->conf))) {
Expand Down
4 changes: 2 additions & 2 deletions src/pages/p_profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private function find_user() {
$user = $this->viewer;
} else if ($this->viewer->privChair
&& ($u === "new" || $u === "bulk")) {
$user = Contact::make($this->conf);
$user = Contact::make_placeholder($this->conf);
$this->page_type = $u === "new" ? 1 : 2;
} else {
$user = $this->handle_user_search($u);
Expand Down Expand Up @@ -288,7 +288,7 @@ private function save_bulk($text, $filename) {
$ustatus->add_csv_synonyms($csv);

while (($line = $csv->next_row())) {
$ustatus->set_user(Contact::make($this->conf));
$ustatus->set_user(Contact::make_placeholder($this->conf));
$ustatus->clear_messages();
$ustatus->jval = (object) ["id" => null];
$ustatus->csvreq = $line;
Expand Down
2 changes: 1 addition & 1 deletion src/reviewinfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ function reviewer() {
if ($this->_reviewer === null) {
$this->prow && $this->prow->ensure_reviewer_names();
$this->_reviewer = $this->conf->user_by_id($this->contactId, USER_SLICE)
?? Contact::make_placeholder($this->conf, $this->contactId);
?? Contact::make_deleted($this->conf, $this->contactId);
}
return $this->_reviewer;
}
Expand Down
28 changes: 18 additions & 10 deletions src/userstatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -891,16 +891,15 @@ function save_user($cj, $old_user = null) {
// ensure/create user
$this->check_invariants($cj);
$actor = $this->viewer->is_root_user() ? null : $this->viewer;
if ($old_user) {
$old_disablement = $old_user->disablement;
} else {
$user = Contact::make_keyed($this->conf, (array) $cj)->store(0, $actor);
if (!$old_user) {
$create_cj = array_merge((array) $cj, ["disablement" => Contact::DISABLEMENT_PLACEHOLDER]);
$user = Contact::make_keyed($this->conf, $create_cj)->store(0, $actor);
$cj->email = $user->email; // adopt contactdb’s email capitalization
$old_disablement = Contact::DISABLEMENT_PLACEHOLDER;
}
if (!$user) {
return null;
}
$old_disablement = $user->disablement;

// initialize
assert(!isset($cj->email) || strcasecmp($cj->email, $user->email) === 0);
Expand Down Expand Up @@ -1013,13 +1012,22 @@ static function save_main(UserStatus $us) {
}

// Disabled
$disablement = $user->disablement & Contact::DISABLEMENT_DB;
if (isset($cj->disabled)) {
$user->set_prop("disabled", $cj->disabled ? Contact::DISABLEMENT_USER : 0);
if ($user->prop_changed("disabled")) {
$us->diffs[$cj->disabled ? "disabled" : "enabled"] = true;
if ($cj->disabled) {
$disablement |= Contact::DISABLEMENT_USER;
} else {
$disablement &= ~Contact::DISABLEMENT_USER;
}
} else { // always revoke placeholder status
$user->activate_placeholder_prop();
}
if ($disablement === Contact::DISABLEMENT_PLACEHOLDER
&& ($us->viewer->is_root_user()
|| $us->conf->allow_user_activate_other())) {
$disablement &= ~Contact::DISABLEMENT_PLACEHOLDER;
}
$user->set_prop("disabled", $disablement);
if ($user->prop_changed("disabled") && isset($cj->disabled)) {
$us->diffs[$cj->disabled ? "disabled" : "enabled"] = true;
}

// Follow
Expand Down

0 comments on commit cdb6dd6

Please sign in to comment.