Exemple #1
0
function upload_grades($pset, $text, $fname)
{
    global $Conf;
    assert($pset->gitless_grades);
    $csv = new CsvParser($text);
    $csv->set_header($csv->next());
    while ($line = $csv->next()) {
        if (($who = get($line, "github_username")) && $who !== "-") {
            $user = $Conf->user_by_query("github_username=?", [$who]);
        } else {
            if (($who = get($line, "seascode_username")) && $who !== "-") {
                $user = $Conf->user_by_query("seascode_username=?", [$who]);
            } else {
                if (($who = get($line, "huid")) && $who !== "-") {
                    $user = $Conf->user_by_query("huid=?", [$who]);
                } else {
                    if (($who = get($line, "username")) && $who !== "-") {
                        $user = $Conf->user_by_query("github_username=? or seascode_username=? order by github_username=? desc limit 1", [$who, $who, $who]);
                    } else {
                        if (($who = get($line, "email")) && $who !== "-") {
                            $user = $Conf->user_by_email($who);
                        } else {
                            if ($who = get($line, "name")) {
                                list($first, $last) = Text::split_name($who);
                                $user = $Conf->user_by_query("firstName like '?s%' and lastName=?", [$first, $last]);
                                if ($user && $user->firstName != $first && !str_starts_with($user->firstName, "{$first} ")) {
                                    $user = null;
                                }
                            } else {
                                continue;
                            }
                        }
                    }
                }
            }
        }
        if ($user) {
            if (!save_grades($user, $pset, null, $line, true)) {
                $Conf->errorMsg("no grades set for “" . htmlspecialchars($who) . "”");
            }
        } else {
            $Conf->errorMsg(htmlspecialchars($fname) . ":" . $csv->lineno() . ": unknown user “" . htmlspecialchars($who) . "”");
        }
    }
    return true;
}
Exemple #2
0
function upload_grades($pset, $text, $fname)
{
    global $Conf;
    assert($pset->gitless_grades);
    $csv = new CsvParser($text);
    $csv->set_header($csv->next());
    while ($line = $csv->next()) {
        if (@$line["seascode_username"]) {
            $who = $line["seascode_username"];
            $user = Contact::find_by_username($who);
        } else {
            if (@$line["email"]) {
                $who = $line["email"];
                $user = Contact::find_by_email($who);
            } else {
                if (@$line["name"]) {
                    $who = $line["name"];
                    list($first, $last) = Text::split_name($who);
                    $user = Contact::find_by_query("firstName like '" . sqlqtrim($first) . "%' and lastName='" . sqlqtrim($last) . "'");
                    if ($user && $user->firstName != $first && !str_starts_with($user->firstName, "{$first} ")) {
                        $user = null;
                    }
                } else {
                    continue;
                }
            }
        }
        if ($user) {
            if (!save_grades($user, $pset, null, $line, true)) {
                $Conf->errorMsg("no grades set for “" . htmlspecialchars($who) . "”");
            }
        } else {
            $Conf->errorMsg(htmlspecialchars($fname) . ":" . $csv->lineno() . ": unknown user “" . htmlspecialchars($who) . "”");
        }
    }
    return true;
}
 static function normalize_name($cj)
 {
     $cj_user = isset($cj->user) ? Text::split_name($cj->user, true) : null;
     $cj_name = Text::analyze_name($cj);
     foreach (array("firstName", "lastName", "email") as $i => $k) {
         if ($cj_name->{$k} !== "" && $cj_name->{$k} !== false) {
             $cj->{$k} = $cj_name->{$k};
         } else {
             if ($cj_user && $cj_user[$i]) {
                 $cj->{$k} = $cj_user[$i];
             }
         }
     }
 }
 private function lookup_users(&$req, $assigner)
 {
     // move all usable identification data to email, firstName, lastName
     if (isset($req["name"])) {
         self::apply_user_parts($req, Text::split_name($req["name"]));
     }
     if (isset($req["user"]) && strpos($req["user"], " ") === false) {
         if (!get($req, "email")) {
             $req["email"] = $req["user"];
         }
     } else {
         if (isset($req["user"])) {
             self::apply_user_parts($req, Text::split_name($req["user"], true));
         }
     }
     // extract email, first, last
     $first = get($req, "firstName");
     $last = get($req, "lastName");
     $email = trim((string) get($req, "email"));
     $lemail = strtolower($email);
     $special = null;
     if ($lemail) {
         $special = $lemail;
     } else {
         if (!$first && $last && strpos(trim($last), " ") === false) {
             $special = trim(strtolower($last));
         }
     }
     $xspecial = $special;
     if ($special === "all") {
         $special = "any";
     }
     // check missing contact
     if (!$first && !$last && !$lemail) {
         if ($assigner->allow_special_contact("missing", $req, $this->astate)) {
             return array(null);
         } else {
             return $this->error("User missing.");
         }
     }
     // check special: "none", "any", "pc", "me", PC tag, "external"
     if ($special === "none" || $special === "any") {
         if (!$assigner->allow_special_contact($special, $req, $this->astate)) {
             return $this->error("User “{$xspecial}” not allowed here.");
         }
         return array((object) array("roles" => 0, "contactId" => null, "email" => $special, "sorter" => ""));
     }
     if ($special && !$first && (!$lemail || !$last)) {
         $ret = ContactSearch::make_special($special, $this->contact->contactId);
         if ($ret->ids !== false) {
             return $ret->contacts();
         }
     }
     if (($special === "ext" || $special === "external") && $assigner->contact_set($req, $this->astate) === "reviewers") {
         $ret = array();
         foreach ($this->reviewer_set() as $u) {
             if (!$u->is_pc_member()) {
                 $ret[] = $u;
             }
         }
         return $ret;
     }
     // check for precise email match on existing contact (common case)
     if ($lemail && ($contact = $this->cmap->lookup_lemail($lemail))) {
         return array($contact);
     }
     // check PC list
     $cset = $assigner->contact_set($req, $this->astate);
     if ($cset === "pc") {
         $cset = pcMembers();
     } else {
         if ($cset === "reviewers") {
             $cset = $this->reviewer_set();
         }
     }
     if ($cset) {
         $text = "";
         if ($first && $last) {
             $text = "{$last}, {$first}";
         } else {
             if ($first || $last) {
                 $text = "{$last}{$first}";
             }
         }
         if ($email) {
             $text .= " <{$email}>";
         }
         $ret = ContactSearch::make_cset($text, $this->contact->cid, $cset);
         if (count($ret->ids) == 1) {
             return $ret->contacts();
         } else {
             if (count($ret->ids) == 0) {
                 $this->error("No user matches “" . self::req_user_html($req) . "”.");
             } else {
                 $this->error("“" . self::req_user_html($req) . "” matches more than one user, use a full email address to disambiguate.");
             }
         }
         return false;
     }
     // create contact
     if (!$email) {
         return $this->error("Missing email address");
     }
     $contact = $this->cmap->make_email($email);
     if ($contact->contactId < 0) {
         if (!validate_email($email)) {
             return $this->error("Email address “" . htmlspecialchars($email) . "” is invalid.");
         }
         if (!isset($contact->firstName) && get($req, "firstName")) {
             $contact->firstName = $req["firstName"];
         }
         if (!isset($contact->lastName) && get($req, "lastName")) {
             $contact->lastName = $req["lastName"];
         }
     }
     return array($contact);
 }
Exemple #5
0
function cleanAuthor($row)
{
    if (!$row || isset($row->authorTable)) {
        return;
    }
    $row->authorTable = array();
    if (strpos($row->authorInformation, "\t") === false) {
        foreach (explode("\n", $row->authorInformation) as $line) {
            if ($line != "") {
                $email = $aff = "";
                if (($p1 = strpos($line, '<')) !== false) {
                    $p2 = strpos($line, '>', $p1);
                    if ($p2 === false) {
                        $p2 = strlen($line);
                    }
                    $email = substr($line, $p1 + 1, $p2 - ($p1 + 1));
                    $line = substr($line, 0, $p1) . substr($line, $p2 + 1);
                }
                if (($p1 = strpos($line, '(')) !== false) {
                    $p2 = strpos($line, ')', $p1);
                    if ($p2 === false) {
                        $p2 = strlen($line);
                    }
                    $aff = substr($line, $p1 + 1, $p2 - ($p1 + 1));
                    $line = substr($line, 0, $p1) . substr($line, $p2 + 1);
                    if (!$email && strpos($aff, '@') !== false && preg_match('_^\\S+@\\S+\\.\\S+$_', $aff)) {
                        $email = $aff;
                        $aff = '';
                    }
                }
                $a = Text::split_name($line);
                $a[2] = $email;
                $a[3] = $aff;
                $row->authorTable[] = $a;
            }
        }
    } else {
        $info = "";
        foreach (explode("\n", $row->authorInformation) as $line) {
            if ($line != "") {
                $row->authorTable[] = $a = explode("\t", $line);
                if ($a[0] && $a[1]) {
                    $info .= "{$a['0']} {$a['1']}";
                } else {
                    $info .= $a[0] . $a[1];
                }
                if ($a[3]) {
                    $info .= " (" . $a[3] . ")";
                } else {
                    if ($a[2]) {
                        $info .= " <" . $a[2] . ">";
                    }
                }
                $info .= "\n";
            }
        }
        $row->authorInformation = $info;
    }
}
function parseBulkFile($text, $filename)
{
    global $Conf;
    $text = cleannl($text);
    if (!is_valid_utf8($text)) {
        $text = windows_1252_to_utf8($text);
    }
    $filename = $filename ? "{$filename}:" : "line ";
    $success = array();
    if (!preg_match('/\\A[^\\r\\n]*(?:,|\\A)(?:user|email)(?:[,\\r\\n]|\\z)/', $text) && !preg_match('/\\A[^\\r\\n]*,[^\\r\\n]*,/', $text)) {
        $tarr = CsvParser::split_lines($text);
        foreach ($tarr as &$t) {
            if (($t = trim($t)) && $t[0] !== "#" && $t[0] !== "%") {
                $t = CsvGenerator::quote($t);
            }
            $t .= "\n";
        }
        unset($t);
        $text = join("", $tarr);
    }
    $csv = new CsvParser($text);
    $csv->set_comment_chars("#%");
    $line = $csv->next();
    if ($line && (array_search("email", $line) !== false || array_search("user", $line) !== false)) {
        $csv->set_header($line);
    } else {
        $csv->set_header(array("user"));
        $csv->unshift($line);
    }
    $cj_template = (object) array();
    $topic_revmap = array();
    foreach ($Conf->topic_map() as $id => $name) {
        $topic_revmap[strtolower($name)] = $id;
    }
    $unknown_topics = array();
    $errors = array();
    while (($line = $csv->next()) !== false) {
        $cj = clone $cj_template;
        foreach ($line as $k => $v) {
            $cj->{$k} = $v;
        }
        foreach (array("firstname" => "firstName", "first" => "firstName", "lastname" => "lastName", "last" => "lastName", "fullname" => "name", "fullName" => "name", "voice" => "voicePhoneNumber", "phone" => "voicePhoneNumber", "address1" => "addressLine1", "province" => "state", "region" => "state", "address2" => "addressLine2", "postalcode" => "zipCode", "zip" => "zipCode", "tags" => "contactTags") as $k => $x) {
            if (isset($cj->{$k}) && !isset($cj->{$x})) {
                $cj->{$x} = $cj->{$k};
            }
        }
        // thou shalt not set passwords by bulk update
        unset($cj->password, $cj->password_plaintext, $cj->new_password);
        if (isset($cj->name) && !isset($cj->firstName) && !isset($cj->lastName)) {
            list($cj->firstName, $cj->lastName) = Text::split_name($cj->name);
        }
        if (count($topic_revmap)) {
            foreach (array_keys($line) as $k) {
                if (preg_match('/^topic:\\s*(.*?)\\s*$/i', $k, $m)) {
                    if (($ti = @$topic_revmap[strtolower($m[1])]) !== null) {
                        $x = $line[$k];
                        if (strtolower($x) === "low") {
                            $x = -2;
                        } else {
                            if (strtolower($x) === "high") {
                                $x = 4;
                            } else {
                                if (!is_numeric($x)) {
                                    $x = 0;
                                }
                            }
                        }
                        if (!@$cj->topics) {
                            $cj->topics = (object) array();
                        }
                        $cj->topics->{$ti} = $x;
                    } else {
                        $unknown_topics[$m[1]] = true;
                    }
                }
            }
        }
        $cj->id = "new";
        $ustatus = new UserStatus(array("send_email" => true, "no_deprivilege_self" => true));
        if ($saved_user = save_user($cj, $ustatus, null, true)) {
            $success[] = "<a href=\"" . hoturl("profile", "u=" . urlencode($saved_user->email)) . "\">" . Text::user_html_nolink($saved_user) . "</a>";
        }
        foreach ($ustatus->error_messages() as $e) {
            $errors[] = "<span class='lineno'>" . $filename . $csv->lineno() . ":</span> " . $e;
        }
    }
    if (count($unknown_topics)) {
        $errors[] = "There were unrecognized topics (" . htmlspecialchars(commajoin($unknown_topics)) . ").";
    }
    if (count($success) == 1) {
        $successMsg = "Saved account " . $success[0] . ".";
    } else {
        if (count($success)) {
            $successMsg = "Saved " . plural($success, "account") . ": " . commajoin($success) . ".";
        }
    }
    if (count($errors)) {
        $errorMsg = "<div class='parseerr'><p>" . join("</p>\n<p>", $errors) . "</p></div>";
    }
    if (count($success) && count($errors)) {
        $Conf->confirmMsg($successMsg . "<br />{$errorMsg}");
    } else {
        if (count($success)) {
            $Conf->confirmMsg($successMsg);
        } else {
            if (count($errors)) {
                Conf::msg_error($errorMsg);
            } else {
                $Conf->warnMsg("Nothing to do.");
            }
        }
    }
    return count($errors) == 0;
}
 private function check_user()
 {
     if (strcasecmp($this->text, "anonymous") == 0 && !$this->cset && !($this->type & self::F_PC)) {
         $result = Dbl::qe_raw("select contactId from ContactInfo where email regexp '^anonymous[0-9]*\$'");
         return Dbl::fetch_first_columns($result);
     }
     // split name components
     list($f, $l, $e) = Text::split_name($this->text, true);
     if ($f === "" && $l === "" && strpos($e, "@") === false) {
         $n = $e;
     } else {
         $n = trim($f . " " . $l);
     }
     // generalize email
     $estar = $e && strpos($e, "*") !== false;
     if ($e && !$estar) {
         if (preg_match('/\\A(.*)@(.*?)((?:[.](?:com|net|edu|org|us|uk|fr|be|jp|cn))?)\\z/', $e, $m)) {
             $e = ($m[1] === "" ? "*" : $m[1]) . "@*" . $m[2] . ($m[3] ?: "*");
         } else {
             $e = "*{$e}*";
         }
     }
     // contact database if not restricted to PC or cset
     $result = null;
     if ($this->cset) {
         $cs = $this->cset;
     } else {
         if ($this->type & self::F_PC) {
             $cs = pcMembers();
         } else {
             $q = array();
             if ($n !== "") {
                 $x = sqlq_for_like(UnicodeHelper::deaccent($n));
                 $q[] = "unaccentedName like '%" . preg_replace('/[\\s*]+/', "%", $x) . "%'";
             }
             if ($e !== "") {
                 $x = sqlq_for_like($e);
                 $q[] = "email like '" . preg_replace('/[\\s*]+/', "%", $x) . "'";
             }
             $result = Dbl::qe_raw("select firstName, lastName, unaccentedName, email, contactId, roles from ContactInfo where " . join(" or ", $q));
             $cs = array();
             while ($result && ($row = Contact::fetch($result))) {
                 $cs[$row->contactId] = $row;
             }
         }
     }
     // filter results
     $nreg = $ereg = null;
     if ($n !== "") {
         $nreg = PaperSearch::analyze_field_preg($n);
     }
     if ($e !== "" && $estar) {
         $ereg = '{\\A' . str_replace('\\*', '.*', preg_quote($e)) . '\\z}i';
     } else {
         if ($e !== "") {
             $ereg = str_replace('@\\*', '@(?:|.*[.])', preg_quote($e));
             $ereg = preg_replace('/\\A\\\\\\*/', '(?:.*[@.]|)', $ereg);
             $ereg = '{\\A' . preg_replace('/\\\\\\*$/', '(?:[@.].*|)', $ereg) . '\\z}i';
         }
     }
     $ids = array();
     foreach ($cs as $id => $acct) {
         if ($ereg && preg_match($ereg, $acct->email)) {
             // exact email match trumps all else
             if (strcasecmp($e, $acct->email) == 0) {
                 $ids = array($id);
                 break;
             }
             $ids[] = $id;
         } else {
             if ($nreg) {
                 $n = $acct->firstName === "" || $acct->lastName === "" ? "" : " ";
                 $n = $acct->firstName . $n . $acct->lastName;
                 if (PaperSearch::match_field_preg($nreg, $n, $acct->unaccentedName)) {
                     $ids[] = $id;
                 }
             }
         }
     }
     Dbl::free($result);
     return $ids;
 }
function ldapLoginAction()
{
    global $Conf, $Opt;
    if (!preg_match('/\\A\\s*(\\S+)\\s+(\\d+\\s+)?([^*]+)\\*(.*?)\\s*\\z/s', $Opt["ldapLogin"], $m)) {
        return Conf::msg_error("Internal error: <code>\$Opt[\"ldapLogin\"]</code> syntax error; expected &ldquo;<code><i>LDAP-URL</i> <i>distinguished-name</i></code>&rdquo;, where <code><i>distinguished-name</i></code> contains a <code>*</code> character to be replaced by the user's email address.  Logins will fail until this error is fixed.");
    }
    // connect to the LDAP server
    if ($m[2] == "") {
        $ldapc = @ldap_connect($m[1]);
    } else {
        $ldapc = @ldap_connect($m[1], (int) $m[2]);
    }
    if (!$ldapc) {
        return Conf::msg_error("Internal error: ldap_connect.  Logins disabled until this error is fixed.");
    }
    @ldap_set_option($ldapc, LDAP_OPT_PROTOCOL_VERSION, 3);
    $qemail = addcslashes(req_s("email"), ',=+<>#;\\"');
    $dn = $m[3] . $qemail . $m[4];
    $success = @ldap_bind($ldapc, $dn, req_s("password"));
    if (!$success && @ldap_errno($ldapc) == 2) {
        @ldap_set_option($ldapc, LDAP_OPT_PROTOCOL_VERSION, 2);
        $success = @ldap_bind($ldapc, $dn, req_s("password"));
    }
    if (!$success) {
        return ldapLoginBindFailure($ldapc);
    }
    // use LDAP information to prepopulate the database with names
    //   add the additional filter key if set
    if (isset($Opt["ldap_addlFilterKey"])) {
        $sr = @ldap_search($ldapc, $dn, "(cn=*)", array("sn", "givenname", "cn", "mail", "telephonenumber", $Opt["ldap_addlFilterKey"]));
    } else {
        $sr = @ldap_search($ldapc, $dn, "(cn=*)", array("sn", "givenname", "cn", "mail", "telephonenumber"));
    }
    if ($sr) {
        $e = @ldap_get_entries($ldapc, $sr);
        $e = $e["count"] == 1 ? $e[0] : array();
        if (isset($e["cn"]) && $e["cn"]["count"] == 1) {
            list($_REQUEST["firstName"], $_REQUEST["lastName"]) = Text::split_name($e["cn"][0]);
        }
        if (isset($e["sn"]) && $e["sn"]["count"] == 1) {
            $_REQUEST["lastName"] = $e["sn"][0];
        }
        if (isset($e["givenname"]) && $e["givenname"]["count"] == 1) {
            $_REQUEST["firstName"] = $e["givenname"][0];
        }
        if (isset($e["mail"]) && $e["mail"]["count"] == 1) {
            $_REQUEST["preferredEmail"] = $e["mail"][0];
        }
        if (isset($e["telephonenumber"]) && $e["telephonenumber"]["count"] == 1) {
            $_REQUEST["voicePhoneNumber"] = $e["telephonenumber"][0];
        }
    }
    // additional filter key set?
    if (isset($Opt["ldap_addlFilterKey"])) {
        // only pass, if key exists in LDAP query, has one value, and the value matches
        //if (!(isset($e[$Opt["ldap_addlFilterKey"]]))) {
        //  return $Conf->errorMsg(" Filter key : '".$Opt["ldap_addlFilterKey"]."' not found in ldap search. " . var_dump(array_keys($e)));
        //}
        //if (!($e[$Opt["ldap_addlFilterKey"]]["count"] == 1)) {
        //  return $Conf->errorMsg("Found wrong number of entries for key: " . $e[$Opt["ldap_addlFilterKey"]]["count"]);
        //}
        if (!(isset($e[$Opt["ldap_addlFilterKey"]]) && $e[$Opt["ldap_addlFilterKey"]]["count"] == 1 && $e[$Opt["ldap_addlFilterKey"]][0] == $Opt["ldap_addlFilterValue"])) {
            return $Conf->errorMsg($Opt["ldap_addlFilterErrMsg"]);
        }
    }
    // set default affiliation
    if (isset($Opt["ldap_def_affiliation"])) {
        $_REQUEST["affiliation"] = $Opt["ldap_def_affiliation"];
    }
    // stick in no collaborators by default (avoids setting popping up all the time)
    if (isset($Opt["ldap_def_collab"])) {
        $_REQUEST["collaborators"] = $Opt["ldap_def_collab"];
    }
    ldap_close($ldapc);
    return true;
}