diff --git a/dist/files_opds-0.8.2.tar.gz b/dist/files_opds-0.8.2.tar.gz
new file mode 100644
index 0000000..614ad60
Binary files /dev/null and b/dist/files_opds-0.8.2.tar.gz differ
diff --git a/files_opds/CHANGELOG.md b/files_opds/CHANGELOG.md
index 9553afd..c66df3c 100644
--- a/files_opds/CHANGELOG.md
+++ b/files_opds/CHANGELOG.md
@@ -1,4 +1,12 @@
-## UNRELEASED
+## 0.8.2 - 2017-01-19
+### Fixed
+ - Support login tokens ('app passwords', NC/OC) and 2FA (NC)
+
+## 0.8.1 - 2017-01-14
+### Changed
+ - more robust preview generator, fallback to mimetype icon when showPreview throws exception
+
+## 0.8.0 - 2017-01-14
### New
- FictionBook 2 (.fb2) metadata parser
- FB2 preview provider
diff --git a/files_opds/README.md b/files_opds/README.md
index 02fe09a..6500cfc 100644
--- a/files_opds/README.md
+++ b/files_opds/README.md
@@ -1,7 +1,7 @@
files_opds
----------
-The OPDS catalog app enables Nextcloud/Owncloud (*-cloud for the rest of this text) users to publish a sub-tree of their personal filesystem as an OPDS feed. Since *-cloud currently has limited to no support for metadata, these are for now stored in a separate table. As of v0.3 OPDS catalog can extract all relevant metadata from EPUB documents. v0.5 introduced ISBN-based metadata retrieval, while Calibre-generated metadata.opf files are parsed since v0.6.
+The OPDS catalog app enables Nextcloud/Owncloud (*-cloud for the rest of this text) users to publish a sub-tree of their personal filesystem as an OPDS feed. Since *-cloud currently has limited to no support for metadata, these are for now stored in a separate table. As of v0.3 OPDS catalog can extract all relevant metadata from EPUB and PDF documents. v0.5 introduced ISBN-based metadata retrieval, while Calibre-generated metadata.opf files are parsed since v0.6. FictionBook 2 (.fb2) metadata is supported from v0.8.0.
#### ISBN
If an ISBN is found in either existing metadata or in the first 10 pages of the publication, metadata is retrieved from ISBNdb (key required, http://isbndb.com/account/logincreate, max. 500 queries/day) and Google Books (no key required).
diff --git a/files_opds/appinfo/info.xml b/files_opds/appinfo/info.xml
index ce8e98c..d7e9a15 100644
--- a/files_opds/appinfo/info.xml
+++ b/files_opds/appinfo/info.xml
@@ -11,7 +11,7 @@
The feed is in compliance with the OPDS 1.1 specification according to the online OPDS validator (http://opds-validator.appspot.com/).
AGPL
- 0.8.0
+ 0.8.2
Frank de Lange
tools
files
diff --git a/files_opds/index.php b/files_opds/index.php
index 48cc1b5..7098f8f 100644
--- a/files_opds/index.php
+++ b/files_opds/index.php
@@ -14,24 +14,14 @@ namespace OCA\Files_Opds;
\OCP\App::checkAppEnabled('files_opds');
-/* Enable login through basic auth, using normal OC username/password
- * This is required because opds clients do not support the normal
- * OC login process
- */
-if (Util::authenticateUser() === false) {
- Util::changeHttpStatus(401);
- exit;
-}
-
-\OCP\User::checkLoggedIn();
+Util::authenticateUser();
/* Refuse access if user disabled opds support */
if (Config::get('enable', 'false') === 'false') {
Util::changeHttpStatus(403);
- exit;
+ exit();
}
-
/* id defaults to 'root' (meaning 'serve root feed') */
$id = isset($_GET['id']) ? $_GET['id'] : 'root';
diff --git a/files_opds/lib/util.php b/files_opds/lib/util.php
index a3b8044..b33cafe 100644
--- a/files_opds/lib/util.php
+++ b/files_opds/lib/util.php
@@ -12,17 +12,28 @@
namespace OCA\Files_Opds;
+use OC\Authentication\Exceptions\PasswordLoginForbiddenException;
+use OC\User\LoginException;
+
/**
* Utility class for OPDS
*/
class Util
{
/**
- * @brief Authenticate user by HTTP Basic Authentication
- * with user name and password
+ * @brief Authenticate user by HTTP Basic Authentication with username and password or token
+ *
+ * Supports login as well as app passwords (tokens).
+ * NC: only app passwords are accepted when 2FA is enforced for $user
+ *
+ * @throws OC\Authentication\Exceptions\PasswordLoginForbiddenException;
+ * @throws OC\User\LoginException;
*/
public static function authenticateUser() {
- if (!isset($_SERVER['PHP_AUTH_USER'])) {
+ $request = \OC::$server->getRequest();
+
+ // force basic auth, enables access through browser
+ if (!isset($request->server['PHP_AUTH_USER'])) {
$defaults = new \OC_Defaults();
$realm = $defaults->getName();
header ("HTTP/1.0 401 Unauthorized");
@@ -30,28 +41,49 @@ class Util
exit();
}
- $userName = $_SERVER['PHP_AUTH_USER'];
+ $user = $request->server['PHP_AUTH_USER'];
+ $pass = $request->server['PHP_AUTH_PW'];
- // Check the password in the ownCloud database
- return self::checkPassword($userName, $_SERVER['PHP_AUTH_PW']);
+ try {
+ //if (!\OC::$server->getUserSession()->logClientIn($user, $pass, $request, $throttler)) {
+ if (!self::logClientIn($user, $pass, $request)) {
+ // unknown user and/or password
+ self::changeHttpStatus(401);
+ exit();
+ }
+ } catch (PasswordLoginForbiddenException $ex) {
+ // 2FA active and enforced for user so only app passwords are allowed
+ self::changeHttpStatus(401);
+ exit();
+ } catch (LoginException $ex) {
+ // login cancelled or user forbidden
+ self::changeHttpStatus(403);
+ exit();
+ }
}
- /**
- * @brief Checks the password of a user.
- * @param string $userName ownCloud user name whose password will be checked.
- * @param string $password ownCloud password.
- * @return bool True if the password is correct, false otherwise.
- *
- */
- private static function checkPassword($userName, $password) {
-
- // Check password normally
- if (\OCP\User::checkPassword($userName, $password) != false) {
- return true;
- }
-
- return false;
- }
+ /**
+ * @brief attempt to login using $user and $pass (password or token)
+ *
+ * Login using username and password, supports both traditional passwords as well as
+ * token-based login ('app passwords').
+ *
+ * @param string $user
+ * @param string $pass
+ * @param IRequest $request
+ * @throws PasswordLoginForbiddenException
+ * @throws LoginException
+ * @return boolean
+ *
+ */
+ public static function logClientIn($user, $pass, $request) {
+ if (class_exists('OC\Security\Bruteforce\Throttler')) {
+ $throttler = \OC::$server->getBruteForceThrottler();
+ return \OC::$server->getUserSession()->logClientIn($user, $pass, $request, $throttler);
+ } else {
+ return \OC::$server->getUserSession()->logClientIn($user, $pass, $request);
+ }
+ }
/**
* @brief Change HTTP response code.