mirror of https://github.com/BOINC/boinc.git
295 lines
9.6 KiB
PHP
Executable File
295 lines
9.6 KiB
PHP
Executable File
#!/usr/bin/env php
|
|
|
|
<?php
|
|
// This file is part of BOINC.
|
|
// http://boinc.berkeley.edu
|
|
// Copyright (C) 2008 University of California
|
|
//
|
|
// BOINC is free software; you can redistribute it and/or modify it
|
|
// under the terms of the GNU Lesser General Public License
|
|
// as published by the Free Software Foundation,
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
//
|
|
// BOINC is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
// fetch a list of "BOINC-wide teams" and create or update them
|
|
|
|
$cli_only = true;
|
|
require_once("../inc/util_ops.inc");
|
|
require_once("../inc/user_util.inc");
|
|
require_once("../inc/team.inc");
|
|
require_once("../inc/email.inc");
|
|
require_once("../project/project.inc");
|
|
require_once("../inc/consent.inc");
|
|
|
|
if (defined('INVITE_CODES')) {
|
|
echo "Account creation is protected by invitation codes, so not importing teams";
|
|
exit;
|
|
}
|
|
|
|
$config = get_config();
|
|
if (parse_bool($config, "disable_account_creation")) {
|
|
echo "Account creation is disabled\n";
|
|
exit;
|
|
}
|
|
|
|
// set the following to 1 to print queries but not do anything
|
|
|
|
$dry_run = 0;
|
|
|
|
function lookup_team_seti_id($seti_id) {
|
|
return BoincTeam::lookup("seti_id=$seti_id");
|
|
}
|
|
|
|
function decode($x) {
|
|
if (!$x) return $x;
|
|
return html_entity_decode($x, ENT_COMPAT, 'UTF-8');
|
|
}
|
|
|
|
function parse_team($f) {
|
|
$t = new stdClass();
|
|
while ($s = fgets($f)) {
|
|
if (strstr($s, '</team>')) {
|
|
$t->name = decode($t->name);
|
|
$t->url = decode($t->url);
|
|
$t->name_html = decode($t->name_html);
|
|
$t->description = decode($t->description);
|
|
$t->user_name = decode($t->user_name);
|
|
$t->user_country = decode($t->user_country);
|
|
$t->user_postal_code = decode($t->user_postal_code);
|
|
$t->user_url = decode($t->user_url);
|
|
return $t;
|
|
}
|
|
else if (strstr($s, '<name>')) $t->name = parse_element($s, '<name>');
|
|
else if (strstr($s, '<url>')) $t->url = parse_element($s, '<url>');
|
|
else if (strstr($s, '<type>')) $t->type = parse_element($s, '<type>');
|
|
else if (strstr($s, '<name_html>')) $t->name_html = parse_element($s, '<name_html>');
|
|
else if (strstr($s, '<description>')) {
|
|
$t->description = '';
|
|
while ($s = fgets($f)) {
|
|
if (strstr($s, '</description>')) break;
|
|
$t->description .= $s;
|
|
}
|
|
}
|
|
else if (strstr($s, '<country>')) $t->country = parse_element($s, '<country>');
|
|
else if (strstr($s, '<id>')) $t->id = parse_element($s, '<id>');
|
|
else if (strstr($s, '<user_email_munged>')) {
|
|
$user_email_munged = parse_element($s, '<user_email_munged>');
|
|
$t->user_email = str_rot13($user_email_munged);
|
|
}
|
|
else if (strstr($s, '<user_name>')) $t->user_name = parse_element($s, '<user_name>');
|
|
else if (strstr($s, '<user_country>')) $t->user_country = parse_element($s, '<user_country>');
|
|
else if (strstr($s, '<user_postal_code>')) $t->user_postal_code = parse_element($s, '<user_postal_code>');
|
|
else if (strstr($s, '<user_url>')) $t->user_url = parse_element($s, '<user_url>');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function valid_team($t) {
|
|
if (!$t->id) return false;
|
|
if (!$t->name) return false;
|
|
if (!$t->user_email) return false;
|
|
if (!$t->user_name) return false;
|
|
return true;
|
|
}
|
|
|
|
function update_team($t, $team, $user) {
|
|
global $dry_run;
|
|
if (
|
|
trim($t->url) == $team->url
|
|
&& $t->type == $team->type
|
|
&& trim($t->name_html) == $team->name_html
|
|
&& trim($t->description) == $team->description
|
|
&& $t->country == $team->country
|
|
&& $t->id == $team->seti_id
|
|
) {
|
|
echo " no changes\n";
|
|
return;
|
|
}
|
|
echo " updating\n";
|
|
$url = BoincDb::escape_string($t->url);
|
|
$name_html = BoincDb::escape_string($t->name_html);
|
|
$description = BoincDb::escape_string($t->description);
|
|
$country = BoincDb::escape_string($t->country);
|
|
$query = "url='$url', type=$t->type, name_html='$name_html', description='$description', country='$country', seti_id=$t->id";
|
|
if ($dry_run) {
|
|
echo " update to team $team->id: $query\n";
|
|
return;
|
|
}
|
|
$retval = $team->update($query);
|
|
if (!$retval) {
|
|
echo " update failed: $query\n";
|
|
exit;
|
|
}
|
|
}
|
|
|
|
function insert_case($t, $user) {
|
|
global $master_url;
|
|
global $dry_run;
|
|
if ($dry_run) {
|
|
if (!$user) echo " making user $t->user_email\n";
|
|
echo " making team $t->name\n";
|
|
return;
|
|
}
|
|
$make_user = FALSE;
|
|
if (!$user) {
|
|
list($checkct, $ctid) = check_consent_type(CONSENT_TYPE_ENROLL);
|
|
if ($checkct) {
|
|
echo " cannot make user when an consent to terms of use is required\n";
|
|
}
|
|
else {
|
|
echo " making user $t->user_email\n";
|
|
$user = make_user($t->user_email, $t->user_name, random_string());
|
|
if (!$user) {
|
|
echo " Can't make user $t->user_email\n";
|
|
return;
|
|
}
|
|
$make_user = TRUE;
|
|
}
|
|
}
|
|
echo " making team $t->name\n";
|
|
// if user was not created, set the userid of a team to be zero
|
|
$myid = 0;
|
|
if ($make_user) {
|
|
$myid = $user->id;
|
|
}
|
|
$team = make_team(
|
|
$myid, $t->name, $t->url, $t->type, $t->name_html,
|
|
$t->description, $t->country
|
|
);
|
|
if (!$team) {
|
|
echo " Can't make team $t->id\n";
|
|
echo BoincDb::error();
|
|
echo "\n";
|
|
exit;
|
|
}
|
|
$team->update("seti_id=$t->id");
|
|
if ($user) {
|
|
$user->update("teamid=$team->id");
|
|
|
|
send_email($user, "Team created on ".PROJECT,
|
|
"An instance of the BOINC-wide team '$t->name'
|
|
has been created on the project:
|
|
name: ".PROJECT."
|
|
URL: $master_url
|
|
"
|
|
);
|
|
}
|
|
}
|
|
|
|
// There are several cases for a given record:
|
|
// (note: "ID" means the ID coming from BOINC, stored locally in seti_id)
|
|
// insert case:
|
|
// There's no team with given name; create one,
|
|
// and create the user if needed
|
|
// update1 case:
|
|
// There's a team with the given name and the given ID
|
|
// and its founder has the right email address.
|
|
// Update its parameters if any are different.
|
|
// update2 case:
|
|
// There's a team with the given name and seti_id=0,
|
|
// and its founder has the right email address.
|
|
// Update its parameters if any are different,
|
|
// and set its seti_id.
|
|
// This handles the case where the team founder created the team
|
|
// before this new system was run.
|
|
// conflict case:
|
|
// There's a team with the given name,
|
|
// and either it has the wrong ID
|
|
// or its founder has a different email address.
|
|
// Don't change anything.
|
|
|
|
// These semantics mean that:
|
|
// - A BOINC team can't change its name via this mechanism.
|
|
// This avoids pathological cases, e.g. if two teams swapped names,
|
|
// the updates would always fail.
|
|
// If a BOINC team wants to change its name,
|
|
// it must do it manually everywhere.
|
|
// - If a BOINC team changes its founder (or the founder changes email)
|
|
// they'll have to make this change manually on all projects.
|
|
// (this is better than a security vulnerability)
|
|
// - This mechanism can't be used to update the founder's
|
|
// account parameters on all projects
|
|
|
|
function handle_team($f) {
|
|
$t = parse_team($f);
|
|
if (!$t) {
|
|
echo "Failed to parse team\n";
|
|
return;
|
|
}
|
|
//print_r($t);
|
|
//return;
|
|
if (!valid_team($t)) {
|
|
echo "Invalid team\n";
|
|
return;
|
|
}
|
|
|
|
echo "Processing $t->name $t->user_email\n";
|
|
$user = BoincUser::lookup_email_addr($t->user_email);
|
|
$team = BoincTeam::lookup_name($t->name);
|
|
if ($team) {
|
|
if (!$user) {
|
|
echo " team exists but user $t->user_email doesn't\n";
|
|
return;
|
|
}
|
|
if ($user->id != $team->userid) {
|
|
echo " team exists but is owned by a different user\n";
|
|
return;
|
|
}
|
|
if ($team->seti_id) {
|
|
if ($team->seti_id == $t->id) {
|
|
echo " case 1\n";
|
|
update_team($t, $team, $user); // update1 case
|
|
} else {
|
|
echo " team exists but has wrong seti_id\n";
|
|
}
|
|
} else {
|
|
$team2 = lookup_team_seti_id($t->id);
|
|
if ($team2) {
|
|
// update1 case
|
|
echo " case 2\n";
|
|
update_team($t, $team2, $user);
|
|
} else {
|
|
// update2 case
|
|
echo " case 3\n";
|
|
update_team($t, $team, $user);
|
|
}
|
|
}
|
|
} else {
|
|
$team = lookup_team_seti_id($t->id);
|
|
if ($team) {
|
|
echo " A team with same ID but different name exists;\n";
|
|
echo " Please report this to $t->user_email;\n";
|
|
} else {
|
|
echo " Adding team\n";
|
|
insert_case($t, $user);
|
|
}
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
echo "------------ Starting at ".time_str(time())."-------\n";
|
|
$f = fopen("http://boinc.berkeley.edu/boinc_teams.xml", "r");
|
|
if (!$f) {
|
|
echo "Can't get times file\n";
|
|
exit;
|
|
}
|
|
while ($s = fgets($f)) {
|
|
if (strstr($s, '<team>')) {
|
|
handle_team($f);
|
|
}
|
|
}
|
|
echo "------------ Finished at ".time_str(time())."-------\n";
|
|
}
|
|
|
|
db_init();
|
|
main();
|
|
|
|
?>
|