Пример #1
0
 /**
  * 验证密码是否符合哈希值
  *
  * @param string $password
  * @param string $salt
  * @param string $hash
  * @return bool
  */
 public function verify($password, $salt, $hash)
 {
     $component = explode('|', $hash);
     if (count($component) < 2) {
         return false;
     }
     if ($component[0] == self::HASH_TYPE_VJ2) {
         if (count($component) !== 3) {
             return false;
         }
         $username = base64_decode($component[1]);
         try {
             $targetHash = self::encode($password, $salt, self::HASH_TYPE_VJ2, $username);
         } catch (\InvalidArgumentException $e) {
             return false;
         }
         return VJ::slowEquals($hash, $targetHash);
     } else {
         if ($component[0] == 'openvj') {
             $targetHash = self::encode($password, $salt, self::HASH_TYPE_OPENVJ);
             try {
                 return VJ::slowEquals($hash, $targetHash);
             } catch (\InvalidArgumentException $e) {
                 return false;
             }
         } else {
             return false;
         }
     }
 }
Пример #2
0
 /**
  * 检验消息和 MAC 是否匹配
  *
  * @param $message
  * @param $sign
  * @return bool
  */
 public function verify($message, $sign)
 {
     if (!is_string($message) || !is_string($sign)) {
         return false;
     }
     $messageSign = $this->sign($message);
     return VJ::slowEquals($messageSign, $sign);
 }
Пример #3
0
 public static function bootstrap()
 {
     Application::Instance();
     Application::get('templating')->addFunction(new \Twig_SimpleFunction('url', function ($relative) {
         return VJ::makeUrl($relative);
     }));
     Application::get('templating')->addFunction(new \Twig_SimpleFunction('getUser', function () {
         return Application::get('user_session')->getUser();
     }));
 }
Пример #4
0
 public function testSlowEquals()
 {
     $this->assertTrue(VJ::slowEquals('abcdefg', 'abcdefg'));
     $this->assertTrue(VJ::slowEquals('abcdEfg', 'abcdEfg'));
     $this->assertTrue(VJ::slowEquals('/abc/*defg', '/abc/*defg'));
     $this->assertFalse(VJ::slowEquals('abcd', 'abc'));
     $this->assertFalse(VJ::slowEquals('abc', 'abcd'));
     $this->assertFalse(VJ::slowEquals('abce', 'abcd'));
     $this->assertFalse(VJ::slowEquals('babc', 'cabc'));
     $this->assertFalse(VJ::slowEquals('abcdef', 'abxdef'));
 }
Пример #5
0
 /**
  * 创建用户
  *
  * @param string $username
  * @param string $password
  * @param string $email
  * @return int UID
  * @throws InvalidArgumentException
  * @throws UserException
  */
 public function createUser($username, $password, $email)
 {
     if (!is_string($username)) {
         throw new InvalidArgumentException('username', 'type_invalid');
     }
     if (!is_string($password)) {
         throw new InvalidArgumentException('password', 'type_invalid');
     }
     if (!is_string($email)) {
         throw new InvalidArgumentException('email', 'type_invalid');
     }
     // 检查用户名
     if (!mb_check_encoding($username, 'UTF-8')) {
         throw new InvalidArgumentException('username', 'encoding_invalid');
     }
     $username = trim($username);
     if (!Validator::regex('/^\\S*$/')->length(3, 16)->validate($username)) {
         throw new InvalidArgumentException('username', 'format_invalid');
     }
     // 检查关键字
     $keyword = KeywordFilter::isContainGeneric($username);
     if ($keyword === false) {
         $keyword = KeywordFilter::isContainName($username);
     }
     if ($keyword !== false) {
         throw new UserException('UserManager.name_forbid', ['keyword' => $keyword]);
     }
     // 检查密码
     if (!Validator::length(0, 50)->validate($password)) {
         throw new InvalidArgumentException('password', 'format_invalid');
     }
     // 检查 email
     if (!Validator::email()->validate($email)) {
         throw new InvalidArgumentException('password', 'format_invalid');
     }
     // 处理用户名
     $username = VJ::removeEmoji($username);
     // 检查用户名和 Email 是否唯一
     if (UserUtil::getUserObjectByUsername($username) !== null) {
         throw new UserException('UserManager.createUser.user_exists');
     }
     if (UserUtil::getUserObjectByEmail($email) !== null) {
         throw new UserException('UserManager.createUser.email_exists');
     }
     // 生成 hash & salt
     $hashSaltPair = $this->user_credential->password_encoder->generateHash($password);
     // 插入记录
     try {
         $_id = new \MongoId();
         $doc = ['_id' => $_id, 'uid' => $_id, 'user' => $username, 'luser' => UserUtil::canonicalizeUsername($username), 'mail' => $email, 'lmail' => UserUtil::canonicalizeEmail($email), 'salt' => $hashSaltPair['salt'], 'hash' => $hashSaltPair['hash'], 'g' => $email, 'gender' => VJ::USER_GENDER_UNKNOWN, 'regat' => new \MongoDate(), 'regip' => $this->request->getClientIp()];
         Application::coll('User')->insert($doc);
     } catch (\MongoCursorException $e) {
         // 插入失败
         throw new UserException('UserManager.createUser.user_or_email_exists');
     }
     // 插入成功:更新 uid
     // 获取递增 uid
     $counterRec = Application::coll('System')->findAndModify(['_id' => 'UserCounter'], ['$inc' => ['count' => 1]], [], ['new' => true, 'upsert' => true]);
     $uid = (int) $counterRec['count'];
     try {
         // 修改 uid
         Application::coll('User')->update(['_id' => $_id], ['$set' => ['uid' => $uid]]);
     } catch (\MongoCursorException $e) {
         // 修改 uid 失败(uid 重复),则删除用户记录
         Application::critical('createUser.uidDuplicate', ['uid' => $uid]);
         Application::coll('User')->remove(['_id' => $_id], ['justOne' => true]);
         throw new UserException('UserManager.createUser.internal');
     }
     Application::emit('user.created', [$uid]);
     return $uid;
 }
Пример #6
0
<?php

/**
 * This file is part of openvj project.
 *
 * Copyright 2013-2015 openvj dev team.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
const MODE_TEST = true;
require __DIR__ . '/../vendor/autoload.php';
\VJ\VJ::bootstrap();
Пример #7
0
 public static function modifyMeta(\MongoId $pid, $title, array $tags, array $visibleDomains)
 {
     if (!is_string($title)) {
         throw new InvalidArgumentException('title', 'type_invalid');
     }
     if (!mb_check_encoding($title, 'UTF-8')) {
         throw new InvalidArgumentException('title', 'encoding_invalid');
     }
     if (!Validator::length(VJ::PROBLEM_TITLE_MIN, VJ::PROBLEM_TITLE_MAX)) {
         throw new UserException('ProblemUtil.title_invalid_length');
     }
     $keyword = KeywordFilter::isContainGeneric($title);
     if ($keyword !== false) {
         throw new UserException('ProblemUtil.title_forbid', ['keyword' => $keyword]);
     }
     foreach ($visibleDomains as $domain) {
         if (!$domain instanceof \MongoId) {
             throw new InvalidArgumentException('visibleDomains', 'type_invalid');
         }
     }
     foreach ($tags as $tag) {
         if (!$tag instanceof Tag) {
             throw new InvalidArgumentException('tags', 'type_invalid');
         }
     }
     $title = VJ::removeEmoji($title);
     $link = self::generateLink($title);
     try {
         $result = Application::coll('Problem')->update(['_id' => $pid], ['$set' => ['title' => $title, 'link' => $link, 'llink' => self::canonicalizeLink($link), 'tags' => array_map(function (Tag $tag) {
             return $tag->serializeForDb();
         }, $tags), 'visible' => $visibleDomains]]);
     } catch (\MongoCursorException $e) {
         throw new UserException('ProblemUtil.modifyMeta.title_exists');
     }
     return $result['n'] === 1;
 }