diff --git a/composer.json b/composer.json index b43f69f5d277f9d092f7abfa57d3b45a25ed338b..f15ff4bdfec6a23ed2d43bd1cd7ae78710ce60f9 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "php": "^7.2", "guzzlehttp/psr7": "^2.3", "neomerx/json-api": "4.0.1", - "spomky-labs/otphp": "^8.3.3", + "spomky-labs/otphp": "^10", "tuupola/cors-middleware": "^1.2.1", "tecnickcom/tcpdf": "^6.3", "scssphp/scssphp": "^1.4", diff --git a/composer.lock b/composer.lock index d3a7eabd7b2109ecc4318d7fd95c1d3f0664e791..78aabd8b4b91308873e96aab98dfa9ddb89d3b02 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5cc4ba67bf29d9dec56b819f4a86e27b", + "content-hash": "09395db276863ae31a0b9e4de81ab3e2", "packages": [ { "name": "algo26-matthias/idna-convert", @@ -64,25 +64,33 @@ }, { "name": "beberlei/assert", - "version": "v2.9.9", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/beberlei/assert.git", - "reference": "124317de301b7c91d5fce34c98bba2c6925bec95" + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/124317de301b7c91d5fce34c98bba2c6925bec95", - "reference": "124317de301b7c91d5fce34c98bba2c6925bec95", + "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-mbstring": "*", - "php": ">=5.3" + "ext-simplexml": "*", + "php": "^7.0 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^2.1.1", - "phpunit/phpunit": "^4.8.35|^5.7" + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": ">=6.0.0", + "yoast/phpunit-polyfills": "^0.1.0" + }, + "suggest": { + "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles" }, "type": "library", "autoload": { @@ -117,9 +125,9 @@ ], "support": { "issues": "https://github.com/beberlei/assert/issues", - "source": "https://github.com/beberlei/assert/tree/v2.9.9" + "source": "https://github.com/beberlei/assert/tree/v3.3.2" }, - "time": "2019-05-28T15:27:37+00:00" + "time": "2021-12-16T21:41:27+00:00" }, { "name": "caxy/php-htmldiff", @@ -2861,34 +2869,41 @@ }, { "name": "spomky-labs/otphp", - "version": "v8.3.3", + "version": "v10.0.3", "source": { "type": "git", "url": "https://github.com/Spomky-Labs/otphp.git", - "reference": "eb14442699ae6470b29ffd89238a9ccfb9f20788" + "reference": "9784d9f7c790eed26e102d6c78f12c754036c366" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/eb14442699ae6470b29ffd89238a9ccfb9f20788", - "reference": "eb14442699ae6470b29ffd89238a9ccfb9f20788", + "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/9784d9f7c790eed26e102d6c78f12c754036c366", + "reference": "9784d9f7c790eed26e102d6c78f12c754036c366", "shasum": "" }, "require": { - "beberlei/assert": "^2.4", - "paragonie/constant_time_encoding": "^1.0|^2.0", - "paragonie/random_compat": ">=2", - "php": "^5.5|^7.0", - "symfony/polyfill-mbstring": "^1.1", - "symfony/polyfill-php56": "^1.1" + "beberlei/assert": "^3.0", + "ext-mbstring": "*", + "paragonie/constant_time_encoding": "^2.0", + "php": "^7.2|^8.0", + "thecodingmachine/safe": "^0.1.14|^1.0|^2.0" }, "require-dev": { - "phpunit/phpunit": "~4.0|^5.0", - "satooshi/php-coveralls": "^1.0" + "php-coveralls/php-coveralls": "^2.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-beberlei-assert": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^8.0", + "thecodingmachine/phpstan-safe-rule": "^1.0 || ^2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.2.x-dev" + "v10.0": "10.0.x-dev", + "v9.0": "9.0.x-dev", + "v8.3": "8.3.x-dev" } }, "autoload": { @@ -2923,9 +2938,9 @@ ], "support": { "issues": "https://github.com/Spomky-Labs/otphp/issues", - "source": "https://github.com/Spomky-Labs/otphp/tree/v8.3" + "source": "https://github.com/Spomky-Labs/otphp/tree/v10.0.3" }, - "time": "2018-09-13T19:25:26+00:00" + "time": "2022-03-17T08:00:35+00:00" }, { "name": "symfony/console", @@ -4038,6 +4053,145 @@ ], "time": "2022-08-12T07:50:54+00:00" }, + { + "name": "thecodingmachine/safe", + "version": "v1.3.3", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/safe.git", + "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/a8ab0876305a4cdaef31b2350fcb9811b5608dbc", + "reference": "a8ab0876305a4cdaef31b2350fcb9811b5608dbc", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpstan/phpstan": "^0.12", + "squizlabs/php_codesniffer": "^3.2", + "thecodingmachine/phpstan-strict-rules": "^0.12" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "files": [ + "deprecated/apc.php", + "deprecated/libevent.php", + "deprecated/mssql.php", + "deprecated/stats.php", + "lib/special_cases.php", + "generated/apache.php", + "generated/apcu.php", + "generated/array.php", + "generated/bzip2.php", + "generated/calendar.php", + "generated/classobj.php", + "generated/com.php", + "generated/cubrid.php", + "generated/curl.php", + "generated/datetime.php", + "generated/dir.php", + "generated/eio.php", + "generated/errorfunc.php", + "generated/exec.php", + "generated/fileinfo.php", + "generated/filesystem.php", + "generated/filter.php", + "generated/fpm.php", + "generated/ftp.php", + "generated/funchand.php", + "generated/gmp.php", + "generated/gnupg.php", + "generated/hash.php", + "generated/ibase.php", + "generated/ibmDb2.php", + "generated/iconv.php", + "generated/image.php", + "generated/imap.php", + "generated/info.php", + "generated/ingres-ii.php", + "generated/inotify.php", + "generated/json.php", + "generated/ldap.php", + "generated/libxml.php", + "generated/lzf.php", + "generated/mailparse.php", + "generated/mbstring.php", + "generated/misc.php", + "generated/msql.php", + "generated/mysql.php", + "generated/mysqli.php", + "generated/mysqlndMs.php", + "generated/mysqlndQc.php", + "generated/network.php", + "generated/oci8.php", + "generated/opcache.php", + "generated/openssl.php", + "generated/outcontrol.php", + "generated/password.php", + "generated/pcntl.php", + "generated/pcre.php", + "generated/pdf.php", + "generated/pgsql.php", + "generated/posix.php", + "generated/ps.php", + "generated/pspell.php", + "generated/readline.php", + "generated/rpminfo.php", + "generated/rrd.php", + "generated/sem.php", + "generated/session.php", + "generated/shmop.php", + "generated/simplexml.php", + "generated/sockets.php", + "generated/sodium.php", + "generated/solr.php", + "generated/spl.php", + "generated/sqlsrv.php", + "generated/ssdeep.php", + "generated/ssh2.php", + "generated/stream.php", + "generated/strings.php", + "generated/swoole.php", + "generated/uodbc.php", + "generated/uopz.php", + "generated/url.php", + "generated/var.php", + "generated/xdiff.php", + "generated/xml.php", + "generated/xmlrpc.php", + "generated/yaml.php", + "generated/yaz.php", + "generated/zip.php", + "generated/zlib.php" + ], + "psr-4": { + "Safe\\": [ + "lib/", + "deprecated/", + "generated/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP core functions that throw exceptions instead of returning FALSE on error", + "support": { + "issues": "https://github.com/thecodingmachine/safe/issues", + "source": "https://github.com/thecodingmachine/safe/tree/v1.3.3" + }, + "time": "2020-10-28T17:51:34+00:00" + }, { "name": "tuupola/callable-handler", "version": "1.1.0", diff --git a/lib/models/TFASecret.php b/lib/models/TFASecret.php index aa863946c9b76eedc0865833cd128b8383c00b61..6d14c8157abd83a34853d0cbc2a5ba7cb0755eec 100644 --- a/lib/models/TFASecret.php +++ b/lib/models/TFASecret.php @@ -1,6 +1,5 @@ <?php use OTPHP\TOTP; -use ParagonIE\ConstantTime\Base32; /** * Model for a two factor authentication secret. @@ -8,6 +7,17 @@ use ParagonIE\ConstantTime\Base32; * @author Jan-Hendrik Willms <tleilax+studip@gmail.com> * @license GPL2 or any later version * @since Stud.IP 4.4 + * + * @property string $id + * @property string $user_id + * @property string $secret + * @property string $type + * @property bool $confirmed + * @property int $mkdate + * @property int $chdate + * + * @property User $user + * @property TFAToken[]|SimpleORMapCollection $tokens */ class TFASecret extends SimpleORMap { @@ -86,9 +96,9 @@ class TFASecret extends SimpleORMap { if ($is_new) { if (!$this->isNew()) { - return; + return true; } - $this->secret = (new TOTP())->getSecret(); + $this->secret = TOTP::create()->getSecret(); $this->confirmed = false; } @@ -133,7 +143,7 @@ class TFASecret extends SimpleORMap */ public function getToken($timestamp = null) { - return $this->getTOTP($this->secret)->at($timestamp ?: time()); + return $this->getTOTP()->at($timestamp ?? time()); } /** @@ -189,13 +199,14 @@ class TFASecret extends SimpleORMap * Returns a totp object used for validation/creation of tokens. * @return TOTP */ - private function getTOTP() + private function getTOTP(): TOTP { - return new TOTP( - $this->user->email, + $totp = TOTP::create( $this->secret, self::TYPES[$this->type]['period'] ); + $totp->setLabel($this->user->email); + return $totp; } /**