diff options
-rw-r--r-- | .mention-bot | 4 | ||||
m--------- | 3rdparty | 0 | ||||
-rw-r--r-- | apps/dav/appinfo/application.php | 60 | ||||
-rw-r--r-- | apps/dav/appinfo/install.php | 2 | ||||
-rw-r--r-- | apps/dav/appinfo/register_command.php | 4 | ||||
-rw-r--r-- | apps/dav/appinfo/v1/publicwebdav.php | 1 | ||||
-rw-r--r-- | apps/dav/bin/chunkperf.php | 76 | ||||
-rw-r--r-- | apps/dav/command/migrateaddressbooks.php | 86 | ||||
-rw-r--r-- | apps/dav/command/migratecalendars.php | 85 | ||||
-rw-r--r-- | apps/dav/lib/caldav/calendar.php | 4 | ||||
-rw-r--r-- | apps/dav/lib/caldav/calendarhome.php | 27 | ||||
-rw-r--r-- | apps/dav/lib/connector/sabre/file.php | 2 | ||||
-rw-r--r-- | apps/dav/lib/connector/sabre/filesplugin.php | 12 | ||||
-rw-r--r-- | apps/dav/lib/hookmanager.php | 6 | ||||
-rw-r--r-- | apps/dav/lib/migration/addressbookadapter.php | 106 | ||||
-rw-r--r-- | apps/dav/lib/migration/calendaradapter.php | 102 | ||||
-rw-r--r-- | apps/dav/lib/migration/migrateaddressbooks.php | 131 | ||||
-rw-r--r-- | apps/dav/lib/migration/migratecalendars.php | 132 | ||||
-rw-r--r-- | apps/dav/lib/rootcollection.php | 4 | ||||
-rw-r--r-- | apps/dav/lib/upload/assemblystream.php | 234 | ||||
-rw-r--r-- | apps/dav/lib/upload/futurefile.php | 103 | ||||
-rw-r--r-- | apps/dav/lib/upload/rootcollection.php | 23 | ||||
-rw-r--r-- | apps/dav/lib/upload/uploadfolder.php | 61 | ||||
-rw-r--r-- | apps/dav/lib/upload/uploadhome.php | 74 | ||||
-rw-r--r-- | apps/dav/tests/unit/caldav/caldavbackendtest.php | 13 | ||||
-rw-r--r-- | apps/dav/tests/unit/caldav/calendartest.php | 24 | ||||
-rw-r--r-- | apps/dav/tests/unit/connector/sabre/filesplugin.php | 33 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/addressbookadaptertest.php | 129 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/calendar_schema.xml | 191 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/calendaradaptertest.php | 131 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/contacts_schema.xml | 151 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/migrateaddressbooktest.php | 81 | ||||
-rw-r--r-- | apps/dav/tests/unit/migration/migratecalendartest.php | 85 | ||||
-rw-r--r-- | apps/dav/tests/unit/upload/assemblystreamtest.php | 47 | ||||
-rw-r--r-- | apps/dav/tests/unit/upload/futurefiletest.php | 89 | ||||
-rw-r--r-- | apps/files/appinfo/application.php | 3 | ||||
-rw-r--r-- | apps/files/appinfo/routes.php | 6 | ||||
-rw-r--r-- | apps/files/controller/apicontroller.php | 32 | ||||
-rw-r--r-- | apps/files/controller/viewcontroller.php | 13 | ||||
-rw-r--r-- | apps/files/js/app.js | 6 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 22 | ||||
-rw-r--r-- | apps/files/templates/index.php | 2 | ||||
-rw-r--r-- | apps/files/tests/controller/ViewControllerTest.php | 22 | ||||
-rw-r--r-- | apps/files/tests/controller/apicontrollertest.php | 55 | ||||
-rw-r--r-- | apps/files/tests/js/filelistSpec.js | 16 | ||||
-rw-r--r-- | apps/files_external/appinfo/app.php | 10 | ||||
-rw-r--r-- | apps/files_external/appinfo/routes.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/api.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/amazons3.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/dropbox.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/ftp.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/google.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/owncloud.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/sftp.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/sftp_key.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/smb.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/smb_oc.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/backend/swift.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/storage/amazons3.php (renamed from apps/files_external/lib/amazons3.php) | 2 | ||||
-rw-r--r-- | apps/files_external/lib/storage/dropbox.php (renamed from apps/files_external/lib/dropbox.php) | 6 | ||||
-rw-r--r-- | apps/files_external/lib/storage/ftp.php (renamed from apps/files_external/lib/ftp.php) | 6 | ||||
-rw-r--r-- | apps/files_external/lib/storage/google.php (renamed from apps/files_external/lib/google.php) | 4 | ||||
-rw-r--r-- | apps/files_external/lib/storage/owncloud.php (renamed from apps/files_external/lib/owncloud.php) | 2 | ||||
-rw-r--r-- | apps/files_external/lib/storage/sftp.php (renamed from apps/files_external/lib/sftp.php) | 2 | ||||
-rw-r--r-- | apps/files_external/lib/storage/smb.php (renamed from apps/files_external/lib/smb.php) | 4 | ||||
-rw-r--r-- | apps/files_external/lib/storage/streamwrapper.php (renamed from apps/files_external/lib/streamwrapper.php) | 4 | ||||
-rw-r--r-- | apps/files_external/lib/storage/swift.php (renamed from apps/files_external/lib/swift.php) | 2 | ||||
-rw-r--r-- | apps/files_external/tests/amazons3migration.php | 10 | ||||
-rw-r--r-- | apps/files_external/tests/controller/storagescontrollertest.php | 14 | ||||
-rw-r--r-- | apps/files_external/tests/controller/userstoragescontrollertest.php | 4 | ||||
-rw-r--r-- | apps/files_external/tests/owncloudfunctions.php | 6 | ||||
-rw-r--r-- | apps/files_external/tests/service/storagesservicetest.php | 6 | ||||
-rw-r--r-- | apps/files_external/tests/storage/amazons3test.php (renamed from apps/files_external/tests/backends/amazons3.php) | 12 | ||||
-rw-r--r-- | apps/files_external/tests/storage/dropboxtest.php (renamed from apps/files_external/tests/backends/dropbox.php) | 12 | ||||
-rw-r--r-- | apps/files_external/tests/storage/ftptest.php (renamed from apps/files_external/tests/backends/ftp.php) | 26 | ||||
-rw-r--r-- | apps/files_external/tests/storage/googletest.php (renamed from apps/files_external/tests/backends/google.php) | 12 | ||||
-rw-r--r-- | apps/files_external/tests/storage/owncloudtest.php (renamed from apps/files_external/tests/backends/owncloud.php) | 12 | ||||
-rw-r--r-- | apps/files_external/tests/storage/sftp_keytest.php (renamed from apps/files_external/tests/backends/sftp_key.php) | 12 | ||||
-rw-r--r-- | apps/files_external/tests/storage/sftptest.php (renamed from apps/files_external/tests/backends/sftp.php) | 16 | ||||
-rw-r--r-- | apps/files_external/tests/storage/smbtest.php (renamed from apps/files_external/tests/backends/smb.php) | 14 | ||||
-rw-r--r-- | apps/files_external/tests/storage/swifttest.php (renamed from apps/files_external/tests/backends/swift.php) | 12 | ||||
-rw-r--r-- | apps/files_external/tests/storage/webdavtest.php (renamed from apps/files_external/tests/backends/webdav.php) | 12 | ||||
-rw-r--r-- | apps/files_sharing/lib/mountprovider.php | 17 | ||||
-rw-r--r-- | apps/files_sharing/lib/sharedmount.php | 47 | ||||
-rw-r--r-- | apps/updatenotification/appinfo/app.php | 7 | ||||
-rw-r--r-- | apps/updatenotification/appinfo/application.php | 7 | ||||
-rw-r--r-- | apps/updatenotification/lib/updatechecker.php | 8 | ||||
-rw-r--r-- | apps/updatenotification/tests/UpdateCheckerTest.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/lib/configuration.php | 3 | ||||
-rw-r--r-- | apps/user_ldap/lib/connection.php | 5 | ||||
-rwxr-xr-x | autotest-external.sh | 7 | ||||
-rw-r--r-- | build/integration/features/bootstrap/WebDav.php | 51 | ||||
-rw-r--r-- | build/integration/features/sharing-v1.feature | 66 | ||||
-rw-r--r-- | build/integration/features/webdav-related.feature | 49 | ||||
-rw-r--r-- | config/config.sample.php | 28 | ||||
-rw-r--r-- | core/Application.php | 15 | ||||
-rw-r--r-- | core/Command/Upgrade.php | 1 | ||||
-rw-r--r-- | core/Controller/LoginController.php | 160 | ||||
-rw-r--r-- | core/ajax/update.php | 11 | ||||
-rw-r--r-- | core/css/header.css | 6 | ||||
-rw-r--r-- | core/css/styles.css | 31 | ||||
-rw-r--r-- | core/css/tooltip.css | 1 | ||||
-rw-r--r-- | core/img/background.jpg | bin | 0 -> 90185 bytes | |||
-rw-r--r-- | core/js/js.js | 19 | ||||
-rw-r--r-- | core/js/placeholder.js | 8 | ||||
-rw-r--r-- | core/l10n/cs_CZ.js | 3 | ||||
-rw-r--r-- | core/l10n/cs_CZ.json | 3 | ||||
-rw-r--r-- | core/l10n/fr.js | 1 | ||||
-rw-r--r-- | core/l10n/fr.json | 1 | ||||
-rw-r--r-- | core/l10n/hu_HU.js | 47 | ||||
-rw-r--r-- | core/l10n/hu_HU.json | 47 | ||||
-rw-r--r-- | core/routes.php | 2 | ||||
-rw-r--r-- | core/templates/login.php | 4 | ||||
-rw-r--r-- | core/templates/update.use-cli.php | 14 | ||||
-rw-r--r-- | lib/base.php | 119 | ||||
-rw-r--r-- | lib/l10n/cs_CZ.js | 9 | ||||
-rw-r--r-- | lib/l10n/cs_CZ.json | 9 | ||||
-rw-r--r-- | lib/l10n/es.js | 11 | ||||
-rw-r--r-- | lib/l10n/es.json | 11 | ||||
-rw-r--r-- | lib/private/App/AppManager.php (renamed from lib/private/app/appmanager.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/AbstractCheck.php (renamed from lib/private/app/codechecker/abstractcheck.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/CodeChecker.php (renamed from lib/private/app/codechecker/codechecker.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/DeprecationCheck.php (renamed from lib/private/app/codechecker/deprecationcheck.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/EmptyCheck.php (renamed from lib/private/app/codechecker/emptycheck.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/ICheck.php (renamed from lib/private/app/codechecker/icheck.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/InfoChecker.php (renamed from lib/private/app/codechecker/infochecker.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/NodeVisitor.php (renamed from lib/private/app/codechecker/nodevisitor.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/PrivateCheck.php (renamed from lib/private/app/codechecker/privatecheck.php) | 0 | ||||
-rw-r--r-- | lib/private/App/CodeChecker/StrongComparisonCheck.php (renamed from lib/private/app/codechecker/strongcomparisoncheck.php) | 0 | ||||
-rw-r--r-- | lib/private/App/DependencyAnalyzer.php (renamed from lib/private/app/dependencyanalyzer.php) | 0 | ||||
-rw-r--r-- | lib/private/App/InfoParser.php (renamed from lib/private/app/infoparser.php) | 0 | ||||
-rw-r--r-- | lib/private/App/Platform.php (renamed from lib/private/app/platform.php) | 0 | ||||
-rw-r--r-- | lib/private/App/PlatformRepository.php (renamed from lib/private/app/platformrepository.php) | 0 | ||||
-rw-r--r-- | lib/private/Cache/CappedMemoryCache.php (renamed from lib/private/cache/cappedmemorycache.php) | 0 | ||||
-rw-r--r-- | lib/private/Cache/File.php (renamed from lib/private/cache/file.php) | 0 | ||||
-rw-r--r-- | lib/private/Command/AsyncBus.php (renamed from lib/private/command/asyncbus.php) | 0 | ||||
-rw-r--r-- | lib/private/Command/CallableJob.php (renamed from lib/private/command/callablejob.php) | 0 | ||||
-rw-r--r-- | lib/private/Command/ClosureJob.php (renamed from lib/private/command/closurejob.php) | 0 | ||||
-rw-r--r-- | lib/private/Command/CommandJob.php (renamed from lib/private/command/commandjob.php) | 0 | ||||
-rw-r--r-- | lib/private/Command/FileAccess.php (renamed from lib/private/command/fileaccess.php) | 0 | ||||
-rw-r--r-- | lib/private/Command/QueueBus.php (renamed from lib/private/command/queuebus.php) | 0 | ||||
-rw-r--r-- | lib/private/Comments/Comment.php (renamed from lib/private/comments/comment.php) | 0 | ||||
-rw-r--r-- | lib/private/Comments/Manager.php (renamed from lib/private/comments/manager.php) | 0 | ||||
-rw-r--r-- | lib/private/Comments/ManagerFactory.php (renamed from lib/private/comments/managerfactory.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/Adapter.php (renamed from lib/private/db/adapter.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/AdapterMySQL.php (renamed from lib/private/db/adaptermysql.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/AdapterOCI8.php (renamed from lib/private/db/adapteroci8.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/AdapterPgSql.php (renamed from lib/private/db/adapterpgsql.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/AdapterSqlite.php (renamed from lib/private/db/adaptersqlite.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/Connection.php (renamed from lib/private/db/connection.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/ConnectionFactory.php (renamed from lib/private/db/connectionfactory.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/MDB2SchemaManager.php (renamed from lib/private/db/mdb2schemamanager.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/MDB2SchemaReader.php (renamed from lib/private/db/mdb2schemareader.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/MDB2SchemaWriter.php (renamed from lib/private/db/mdb2schemawriter.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/MigrationException.php (renamed from lib/private/db/migrationexception.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/Migrator.php (renamed from lib/private/db/migrator.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/MySQLMigrator.php (renamed from lib/private/db/mysqlmigrator.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/NoCheckMigrator.php (renamed from lib/private/db/nocheckmigrator.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/OCSqlitePlatform.php (renamed from lib/private/db/ocsqliteplatform.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/OracleConnection.php (renamed from lib/private/db/oracleconnection.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/OracleMigrator.php (renamed from lib/private/db/oraclemigrator.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/PgSqlTools.php (renamed from lib/private/db/pgsqltools.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/CompositeExpression.php (renamed from lib/private/db/querybuilder/compositeexpression.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php (renamed from lib/private/db/querybuilder/expressionbuilder/expressionbuilder.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php (renamed from lib/private/db/querybuilder/expressionbuilder/mysqlexpressionbuilder.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/ExpressionBuilder/OCIExpressionBuilder.php (renamed from lib/private/db/querybuilder/expressionbuilder/ociexpressionbuilder.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/ExpressionBuilder/PgSqlExpressionBuilder.php (renamed from lib/private/db/querybuilder/expressionbuilder/pgsqlexpressionbuilder.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/Literal.php (renamed from lib/private/db/querybuilder/literal.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/Parameter.php (renamed from lib/private/db/querybuilder/parameter.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QueryBuilder.php (renamed from lib/private/db/querybuilder/querybuilder.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QueryFunction.php (renamed from lib/private/db/querybuilder/queryfunction.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/QueryBuilder/QuoteHelper.php (renamed from lib/private/db/querybuilder/quotehelper.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/SQLiteMigrator.php (renamed from lib/private/db/sqlitemigrator.php) | 0 | ||||
-rw-r--r-- | lib/private/DB/SQLiteSessionInit.php (renamed from lib/private/db/sqlitesessioninit.php) | 0 | ||||
-rw-r--r-- | lib/private/Lock/AbstractLockingProvider.php (renamed from lib/private/lock/abstractlockingprovider.php) | 0 | ||||
-rw-r--r-- | lib/private/Lock/DBLockingProvider.php (renamed from lib/private/lock/dblockingprovider.php) | 0 | ||||
-rw-r--r-- | lib/private/Lock/MemcacheLockingProvider.php (renamed from lib/private/lock/memcachelockingprovider.php) | 0 | ||||
-rw-r--r-- | lib/private/Lock/NoopLockingProvider.php (renamed from lib/private/lock/nooplockingprovider.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/APC.php (renamed from lib/private/memcache/apc.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/APCu.php (renamed from lib/private/memcache/apcu.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/ArrayCache.php (renamed from lib/private/memcache/arraycache.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/CADTrait.php (renamed from lib/private/memcache/cadtrait.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/CASTrait.php (renamed from lib/private/memcache/castrait.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/Cache.php (renamed from lib/private/memcache/cache.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/Factory.php (renamed from lib/private/memcache/factory.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/Memcached.php (renamed from lib/private/memcache/memcached.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/NullCache.php (renamed from lib/private/memcache/nullcache.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/Redis.php (renamed from lib/private/memcache/redis.php) | 0 | ||||
-rw-r--r-- | lib/private/Memcache/XCache.php (renamed from lib/private/memcache/xcache.php) | 0 | ||||
-rw-r--r-- | lib/private/Notification/Action.php (renamed from lib/private/notification/action.php) | 0 | ||||
-rw-r--r-- | lib/private/Notification/Manager.php (renamed from lib/private/notification/manager.php) | 0 | ||||
-rw-r--r-- | lib/private/Notification/Notification.php (renamed from lib/private/notification/notification.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CSP/ContentSecurityPolicy.php (renamed from lib/private/security/csp/contentsecuritypolicy.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CSP/ContentSecurityPolicyManager.php (renamed from lib/private/security/csp/contentsecuritypolicymanager.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CSRF/CsrfToken.php (renamed from lib/private/security/csrf/csrftoken.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CSRF/CsrfTokenGenerator.php (renamed from lib/private/security/csrf/csrftokengenerator.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CSRF/CsrfTokenManager.php (renamed from lib/private/security/csrf/csrftokenmanager.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CSRF/TokenStorage/SessionStorage.php (renamed from lib/private/security/csrf/tokenstorage/sessionstorage.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/Certificate.php (renamed from lib/private/security/certificate.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CertificateManager.php (renamed from lib/private/security/certificatemanager.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/CredentialsManager.php (renamed from lib/private/security/credentialsmanager.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/Crypto.php (renamed from lib/private/security/crypto.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/Hasher.php (renamed from lib/private/security/hasher.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/SecureRandom.php (renamed from lib/private/security/securerandom.php) | 0 | ||||
-rw-r--r-- | lib/private/Security/TrustedDomainHelper.php (renamed from lib/private/security/trusteddomainhelper.php) | 0 | ||||
-rw-r--r-- | lib/private/Server.php | 3 | ||||
-rw-r--r-- | lib/private/Session/CryptoSessionData.php (renamed from lib/private/session/cryptosessiondata.php) | 0 | ||||
-rw-r--r-- | lib/private/Session/CryptoWrapper.php (renamed from lib/private/session/cryptowrapper.php) | 0 | ||||
-rw-r--r-- | lib/private/Session/Internal.php (renamed from lib/private/session/internal.php) | 0 | ||||
-rw-r--r-- | lib/private/Session/Memory.php (renamed from lib/private/session/memory.php) | 0 | ||||
-rw-r--r-- | lib/private/Session/Session.php (renamed from lib/private/session/session.php) | 0 | ||||
-rw-r--r-- | lib/private/api.php | 2 | ||||
-rw-r--r-- | lib/private/appframework/http/request.php | 2 | ||||
-rw-r--r-- | lib/private/appframework/middleware/security/securitymiddleware.php | 9 | ||||
-rw-r--r-- | lib/private/files/cache/scanner.php | 50 | ||||
-rw-r--r-- | lib/private/legacy/db/statementwrapper.php (renamed from lib/private/db/statementwrapper.php) | 0 | ||||
-rw-r--r-- | lib/private/share/share.php | 21 | ||||
-rw-r--r-- | lib/private/template/base.php | 13 | ||||
-rw-r--r-- | lib/private/templatelayout.php | 4 | ||||
-rw-r--r-- | lib/private/updater.php | 66 | ||||
-rw-r--r-- | lib/private/updater/versioncheck.php | 133 | ||||
-rw-r--r-- | lib/private/user.php | 18 | ||||
-rw-r--r-- | lib/private/util.php | 41 | ||||
-rw-r--r-- | lib/public/irequest.php | 2 | ||||
-rw-r--r-- | lib/public/user.php | 2 | ||||
-rw-r--r-- | remote.php | 5 | ||||
-rw-r--r-- | settings/js/users/deleteHandler.js | 2 | ||||
-rw-r--r-- | settings/l10n/cs_CZ.js | 1 | ||||
-rw-r--r-- | settings/l10n/cs_CZ.json | 1 | ||||
-rw-r--r-- | settings/l10n/es.js | 2 | ||||
-rw-r--r-- | settings/l10n/es.json | 2 | ||||
-rw-r--r-- | settings/l10n/fi_FI.js | 1 | ||||
-rw-r--r-- | settings/l10n/fi_FI.json | 1 | ||||
-rw-r--r-- | settings/l10n/it.js | 1 | ||||
-rw-r--r-- | settings/l10n/it.json | 1 | ||||
-rw-r--r-- | settings/l10n/pt_BR.js | 1 | ||||
-rw-r--r-- | settings/l10n/pt_BR.json | 1 | ||||
-rw-r--r-- | settings/l10n/sq.js | 1 | ||||
-rw-r--r-- | settings/l10n/sq.json | 1 | ||||
-rw-r--r-- | settings/l10n/sv.js | 1 | ||||
-rw-r--r-- | settings/l10n/sv.json | 1 | ||||
-rw-r--r-- | settings/tests/js/users/deleteHandlerSpec.js | 14 | ||||
-rw-r--r-- | tests/core/controller/LoginControllerTest.php | 267 | ||||
-rw-r--r-- | tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php | 13 | ||||
-rw-r--r-- | tests/lib/updater.php | 239 | ||||
-rw-r--r-- | tests/lib/updater/versioncheck.php | 289 | ||||
-rw-r--r-- | tests/phpunit-autotest-external.xml | 2 |
247 files changed, 2521 insertions, 2258 deletions
diff --git a/.mention-bot b/.mention-bot index 5997a7a03bb..91ad57d8509 100644 --- a/.mention-bot +++ b/.mention-bot @@ -11,8 +11,8 @@ { "name": "nickvergessen", "files": [ - "lib/private/activity/**", - "lib/private/notification/**", + "lib/private/Activity/**", + "lib/private/Notification/**", "lib/public/activity/**", "lib/public/notification/**" ] diff --git a/3rdparty b/3rdparty -Subproject 631b7de7cebfb85f4877bbb77ff32c1b735c1ee +Subproject 182a1040823e45b0c5664818711dc783a2ca57a diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 593cd770be5..c3811a40845 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -30,10 +30,6 @@ use OCA\DAV\CardDAV\SyncService; use OCA\DAV\Connector\Sabre\Principal; use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\HookManager; -use OCA\Dav\Migration\AddressBookAdapter; -use OCA\Dav\Migration\CalendarAdapter; -use OCA\Dav\Migration\MigrateAddressbooks; -use OCA\Dav\Migration\MigrateCalendars; use \OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; use OCP\Contacts\IManager; @@ -98,30 +94,6 @@ class Application extends App { return new CalDavBackend($db, $principal); }); - $container->registerService('MigrateAddressbooks', function($c) { - /** @var IAppContainer $c */ - $db = $c->getServer()->getDatabaseConnection(); - $logger = $c->getServer()->getLogger(); - return new MigrateAddressbooks( - new AddressBookAdapter($db), - $c->query('CardDavBackend'), - $logger, - null - ); - }); - - $container->registerService('MigrateCalendars', function($c) { - /** @var IAppContainer $c */ - $db = $c->getServer()->getDatabaseConnection(); - $logger = $c->getServer()->getLogger(); - return new MigrateCalendars( - new CalendarAdapter($db), - $c->query('CalDavBackend'), - $logger, - null - ); - }); - $container->registerService('BirthdayService', function($c) { /** @var IAppContainer $c */ $g = new GroupPrincipalBackend( @@ -186,38 +158,6 @@ class Application extends App { $jl->add(new SyncJob()); } - public function migrateAddressbooks() { - try { - /** @var MigrateAddressbooks $migration */ - $migration = $this->getContainer()->query('MigrateAddressbooks'); - $migration->setup(); - $userManager = $this->getContainer()->getServer()->getUserManager(); - - $userManager->callForAllUsers(function($user) use($migration) { - /** @var IUser $user */ - $migration->migrateForUser($user->getUID()); - }); - } catch (\Exception $ex) { - $this->getContainer()->getServer()->getLogger()->logException($ex); - } - } - - public function migrateCalendars() { - try { - /** @var MigrateCalendars $migration */ - $migration = $this->getContainer()->query('MigrateCalendars'); - $migration->setup(); - $userManager = $this->getContainer()->getServer()->getUserManager(); - - $userManager->callForAllUsers(function($user) use($migration) { - /** @var IUser $user */ - $migration->migrateForUser($user->getUID()); - }); - } catch (\Exception $ex) { - $this->getContainer()->getServer()->getLogger()->logException($ex); - } - } - public function generateBirthdays() { try { /** @var BirthdayService $migration */ diff --git a/apps/dav/appinfo/install.php b/apps/dav/appinfo/install.php index dc5ae39226e..fbd41d25f49 100644 --- a/apps/dav/appinfo/install.php +++ b/apps/dav/appinfo/install.php @@ -23,6 +23,4 @@ use OCA\Dav\AppInfo\Application; $app = new Application(); $app->setupCron(); -$app->migrateAddressbooks(); -$app->migrateCalendars(); $app->generateBirthdays(); diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 570848f0b23..b3ab25a99e3 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -21,8 +21,6 @@ use OCA\Dav\AppInfo\Application; use OCA\DAV\Command\CreateAddressBook; use OCA\DAV\Command\CreateCalendar; -use OCA\Dav\Command\MigrateAddressbooks; -use OCA\Dav\Command\MigrateCalendars; use OCA\DAV\Command\SyncBirthdayCalendar; use OCA\DAV\Command\SyncSystemAddressBook; @@ -37,5 +35,3 @@ $application->add(new CreateCalendar($userManager, $groupManager, $dbConnection) $application->add(new CreateAddressBook($userManager, $app->getContainer()->query('CardDavBackend'))); $application->add(new SyncSystemAddressBook($app->getSyncService())); $application->add(new SyncBirthdayCalendar($userManager, $app->getContainer()->query('BirthdayService'))); -$application->add(new MigrateAddressbooks($userManager, $app->getContainer()->query('MigrateAddressbooks'))); -$application->add(new MigrateCalendars($userManager, $app->getContainer()->query('MigrateCalendars'))); diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php index b26e9ebe7c8..43fedb19415 100644 --- a/apps/dav/appinfo/v1/publicwebdav.php +++ b/apps/dav/appinfo/v1/publicwebdav.php @@ -30,6 +30,7 @@ $RUNTIME_APPTYPES = ['filesystem', 'authentication', 'logging']; OC_App::loadApps($RUNTIME_APPTYPES); OC_Util::obEnd(); +\OC::$server->getSession()->close(); // Backends $authBackend = new OCA\DAV\Connector\PublicAuth( diff --git a/apps/dav/bin/chunkperf.php b/apps/dav/bin/chunkperf.php new file mode 100644 index 00000000000..a193f001a41 --- /dev/null +++ b/apps/dav/bin/chunkperf.php @@ -0,0 +1,76 @@ +<?php +/** + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +require '../../../../3rdparty/autoload.php'; + +if ($argc !== 6) { + echo "Invalid number of arguments" . PHP_EOL; + exit; +} + +/** + * @param \Sabre\DAV\Client $client + * @param $uploadUrl + * @return mixed + */ +function request($client, $method, $uploadUrl, $data = null, $headers = []) { + echo "$method $uploadUrl ... "; + $t0 = microtime(true); + $result = $client->request($method, $uploadUrl, $data, $headers); + $t1 = microtime(true); + echo $result['statusCode'] . " - " . ($t1 - $t0) . ' seconds' . PHP_EOL; + if (!in_array($result['statusCode'], [200, 201])) { + echo $result['body'] . PHP_EOL; + } + return $result; +} + +$baseUri = $argv[1]; +$userName = $argv[2]; +$password = $argv[3]; +$file = $argv[4]; +$chunkSize = $argv[5] * 1024 * 1024; + +$client = new \Sabre\DAV\Client([ + 'baseUri' => $baseUri, + 'userName' => $userName, + 'password' => $password +]); + +$transfer = uniqid('transfer', true); +$uploadUrl = "$baseUri/uploads/$userName/$transfer"; + +request($client, 'MKCOL', $uploadUrl); + +$size = filesize($file); +$stream = fopen($file, 'r'); + +$index = 0; +while(!feof($stream)) { + request($client, 'PUT', "$uploadUrl/$index", fread($stream, $chunkSize)); + $index++; +} + +$destination = pathinfo($file, PATHINFO_BASENAME); +//echo "Moving $uploadUrl/.file to it's final destination $baseUri/files/$userName/$destination" . PHP_EOL; +request($client, 'MOVE', "$uploadUrl/.file", null, [ + 'Destination' => "$baseUri/files/$userName/$destination" +]); diff --git a/apps/dav/command/migrateaddressbooks.php b/apps/dav/command/migrateaddressbooks.php deleted file mode 100644 index 562f19a2300..00000000000 --- a/apps/dav/command/migrateaddressbooks.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OCA\Dav\Command; - -use OCP\IUser; -use OCP\IUserManager; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class MigrateAddressbooks extends Command { - - /** @var IUserManager */ - protected $userManager; - - /** @var \OCA\Dav\Migration\MigrateAddressbooks */ - private $service; - - /** - * @param IUserManager $userManager - * @param \OCA\Dav\Migration\MigrateAddressbooks $service - */ - function __construct(IUserManager $userManager, - \OCA\Dav\Migration\MigrateAddressbooks $service - ) { - parent::__construct(); - $this->userManager = $userManager; - $this->service = $service; - } - - protected function configure() { - $this - ->setName('dav:migrate-addressbooks') - ->setDescription('Migrate addressbooks from the contacts app to core') - ->addArgument('user', - InputArgument::OPTIONAL, - 'User for whom all addressbooks will be migrated'); - } - - protected function execute(InputInterface $input, OutputInterface $output) { - $this->service->setup(); - - $user = $input->getArgument('user'); - if (!is_null($user)) { - if (!$this->userManager->userExists($user)) { - throw new \InvalidArgumentException("User <$user> in unknown."); - } - $output->writeln("Start migration for $user"); - $this->service->migrateForUser($user); - return; - } - $output->writeln("Start migration of all known users ..."); - $p = new ProgressBar($output); - $p->start(); - $this->userManager->callForAllUsers(function($user) use ($p) { - $p->advance(); - /** @var IUser $user */ - $this->service->migrateForUser($user->getUID()); - }); - - $p->finish(); - $output->writeln(''); - } -} diff --git a/apps/dav/command/migratecalendars.php b/apps/dav/command/migratecalendars.php deleted file mode 100644 index d887309ac3e..00000000000 --- a/apps/dav/command/migratecalendars.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Command; - -use OCP\IUser; -use OCP\IUserManager; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class MigrateCalendars extends Command { - - /** @var IUserManager */ - protected $userManager; - - /** @var \OCA\Dav\Migration\MigrateCalendars */ - private $service; - - /** - * @param IUserManager $userManager - * @param \OCA\Dav\Migration\MigrateCalendars $service - */ - function __construct(IUserManager $userManager, - \OCA\Dav\Migration\MigrateCalendars $service - ) { - parent::__construct(); - $this->userManager = $userManager; - $this->service = $service; - } - - protected function configure() { - $this - ->setName('dav:migrate-calendars') - ->setDescription('Migrate calendars from the calendar app to core') - ->addArgument('user', - InputArgument::OPTIONAL, - 'User for whom all calendars will be migrated'); - } - - protected function execute(InputInterface $input, OutputInterface $output) { - $this->service->setup(); - - $user = $input->getArgument('user'); - if (!is_null($user)) { - if (!$this->userManager->userExists($user)) { - throw new \InvalidArgumentException("User <$user> in unknown."); - } - $output->writeln("Start migration for $user"); - $this->service->migrateForUser($user); - return; - } - $output->writeln("Start migration of all known users ..."); - $p = new ProgressBar($output); - $p->start(); - $this->userManager->callForAllUsers(function($user) use ($p) { - $p->advance(); - /** @var IUser $user */ - $this->service->migrateForUser($user->getUID()); - }); - - $p->finish(); - $output->writeln(''); - } -} diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 5072d96107e..6d6c0b5d7a4 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -22,17 +22,19 @@ namespace OCA\DAV\CalDAV; use OCA\DAV\DAV\Sharing\IShareable; +use OCP\IL10N; use Sabre\CalDAV\Backend\BackendInterface; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\PropPatch; class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { - public function __construct(BackendInterface $caldavBackend, $calendarInfo) { + public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n) { parent::__construct($caldavBackend, $calendarInfo); if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) { $this->calendarInfo['{http://sabredav.org/ns}read-only'] = true; + $this->calendarInfo['{DAV:}displayname'] = $l10n->t('Contact birthdays'); } } diff --git a/apps/dav/lib/caldav/calendarhome.php b/apps/dav/lib/caldav/calendarhome.php index 87b8d4bb320..a4c485a8983 100644 --- a/apps/dav/lib/caldav/calendarhome.php +++ b/apps/dav/lib/caldav/calendarhome.php @@ -21,6 +21,7 @@ */ namespace OCA\DAV\CalDAV; +use Sabre\CalDAV\Backend\BackendInterface; use Sabre\CalDAV\Backend\NotificationSupport; use Sabre\CalDAV\Backend\SchedulingSupport; use Sabre\CalDAV\Backend\SubscriptionSupport; @@ -31,34 +32,42 @@ use Sabre\DAV\Exception\NotFound; class CalendarHome extends \Sabre\CalDAV\CalendarHome { + /** @var \OCP\IL10N */ + private $l10n; + + public function __construct(BackendInterface $caldavBackend, $principalInfo) { + parent::__construct($caldavBackend, $principalInfo); + $this->l10n = \OC::$server->getL10N('dav'); + } + /** * @inheritdoc */ function getChildren() { $calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']); - $objs = []; + $objects = []; foreach ($calendars as $calendar) { - $objs[] = new Calendar($this->caldavBackend, $calendar); + $objects[] = new Calendar($this->caldavBackend, $calendar, $this->l10n); } if ($this->caldavBackend instanceof SchedulingSupport) { - $objs[] = new Inbox($this->caldavBackend, $this->principalInfo['uri']); - $objs[] = new Outbox($this->principalInfo['uri']); + $objects[] = new Inbox($this->caldavBackend, $this->principalInfo['uri']); + $objects[] = new Outbox($this->principalInfo['uri']); } // We're adding a notifications node, if it's supported by the backend. if ($this->caldavBackend instanceof NotificationSupport) { - $objs[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']); + $objects[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']); } // If the backend supports subscriptions, we'll add those as well, if ($this->caldavBackend instanceof SubscriptionSupport) { foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) { - $objs[] = new Subscription($this->caldavBackend, $subscription); + $objects[] = new Subscription($this->caldavBackend, $subscription); } } - return $objs; + return $objects; } /** @@ -79,7 +88,7 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome { // Calendars foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) { if ($calendar['uri'] === $name) { - return new Calendar($this->caldavBackend, $calendar); + return new Calendar($this->caldavBackend, $calendar, $this->l10n); } } @@ -94,4 +103,4 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome { throw new NotFound('Node with name \'' . $name . '\' could not be found'); } -}
\ No newline at end of file +} diff --git a/apps/dav/lib/connector/sabre/file.php b/apps/dav/lib/connector/sabre/file.php index 6b698c6e5a9..943e9150e74 100644 --- a/apps/dav/lib/connector/sabre/file.php +++ b/apps/dav/lib/connector/sabre/file.php @@ -143,7 +143,7 @@ class File extends Node implements IFile { // if content length is sent by client: // double check if the file was fully received // compare expected and actual size - if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] !== 'LOCK') { + if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') { $expected = $_SERVER['CONTENT_LENGTH']; if ($count != $expected) { throw new BadRequest('expected filesize ' . $expected . ' got ' . $count); diff --git a/apps/dav/lib/connector/sabre/filesplugin.php b/apps/dav/lib/connector/sabre/filesplugin.php index 8b54291793a..686d0863f91 100644 --- a/apps/dav/lib/connector/sabre/filesplugin.php +++ b/apps/dav/lib/connector/sabre/filesplugin.php @@ -28,24 +28,26 @@ namespace OCA\DAV\Connector\Sabre; use OC\Files\View; +use OCA\DAV\Upload\FutureFile; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\IFile; use \Sabre\DAV\PropFind; use \Sabre\DAV\PropPatch; +use Sabre\DAV\ServerPlugin; use Sabre\DAV\Tree; use \Sabre\HTTP\RequestInterface; use \Sabre\HTTP\ResponseInterface; use OCP\Files\StorageNotAvailableException; -class FilesPlugin extends \Sabre\DAV\ServerPlugin { +class FilesPlugin extends ServerPlugin { // namespace const NS_OWNCLOUD = 'http://owncloud.org/ns'; const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id'; const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid'; const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions'; - const SHARE_PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}share-permissions'; + const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions'; const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL'; const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size'; const GETETAG_PROPERTYNAME = '{DAV:}getetag'; @@ -146,11 +148,17 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { /** * Plugin that checks if a move can actually be performed. + * * @param string $source source path * @param string $destination destination path * @throws Forbidden + * @throws NotFound */ function checkMove($source, $destination) { + $sourceNode = $this->tree->getNodeForPath($source); + if ($sourceNode instanceof FutureFile) { + return; + } list($sourceDir,) = \Sabre\HTTP\URLUtil::splitPath($source); list($destinationDir,) = \Sabre\HTTP\URLUtil::splitPath($destination); diff --git a/apps/dav/lib/hookmanager.php b/apps/dav/lib/hookmanager.php index c3d68a3ee2a..4a4704ff2a2 100644 --- a/apps/dav/lib/hookmanager.php +++ b/apps/dav/lib/hookmanager.php @@ -105,7 +105,8 @@ class HookManager { $calendars = $this->calDav->getCalendarsForUser($principal); if (empty($calendars)) { try { - $this->calDav->createCalendar($principal, 'default', []); + $this->calDav->createCalendar($principal, 'personal', [ + 'displayname' => 'Personal']); } catch (\Exception $ex) { \OC::$server->getLogger()->logException($ex); } @@ -113,7 +114,8 @@ class HookManager { $books = $this->cardDav->getAddressBooksForUser($principal); if (empty($books)) { try { - $this->cardDav->createAddressBook($principal, 'default', []); + $this->cardDav->createAddressBook($principal, 'contacts', [ + 'displayname' => 'Contacts']); } catch (\Exception $ex) { \OC::$server->getLogger()->logException($ex); } diff --git a/apps/dav/lib/migration/addressbookadapter.php b/apps/dav/lib/migration/addressbookadapter.php deleted file mode 100644 index 5264747a004..00000000000 --- a/apps/dav/lib/migration/addressbookadapter.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCP\IDBConnection; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class AddressBookAdapter { - - /** @var \OCP\IDBConnection */ - protected $dbConnection; - - /** @var string */ - private $sourceBookTable; - - /** @var string */ - private $sourceCardsTable; - - /** - * @param IDBConnection $dbConnection - * @param string $sourceBookTable - * @param string $sourceCardsTable - */ - function __construct(IDBConnection $dbConnection, - $sourceBookTable = 'contacts_addressbooks', - $sourceCardsTable = 'contacts_cards') { - $this->dbConnection = $dbConnection; - $this->sourceBookTable = $sourceBookTable; - $this->sourceCardsTable = $sourceCardsTable; - } - - /** - * @param string $user - * @param \Closure $callBack - */ - public function foreachBook($user, \Closure $callBack) { - // get all addressbooks of that user - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceBookTable) - ->where($query->expr()->eq('userid', $query->createNamedParameter($user))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - public function setup() { - if (!$this->dbConnection->tableExists($this->sourceBookTable)) { - throw new \DomainException('Contacts tables are missing. Nothing to do.'); - } - } - - /** - * @param int $addressBookId - * @param \Closure $callBack - */ - public function foreachCard($addressBookId, \Closure $callBack) { - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceCardsTable) - ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - /** - * @param int $addressBookId - * @return array - */ - public function getShares($addressBookId) { - $query = $this->dbConnection->getQueryBuilder(); - $shares = $query->select('*')->from('share') - ->where($query->expr()->eq('item_source', $query->createNamedParameter($addressBookId))) - ->andWhere($query->expr()->eq('item_type', $query->expr()->literal('addressbook'))) - ->andWhere($query->expr()->in('share_type', [ $query->expr()->literal(0), $query->expr()->literal(1)])) - ->execute() - ->fetchAll(); - - return $shares; - } -} diff --git a/apps/dav/lib/migration/calendaradapter.php b/apps/dav/lib/migration/calendaradapter.php deleted file mode 100644 index d02f2256c34..00000000000 --- a/apps/dav/lib/migration/calendaradapter.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCP\IDBConnection; - -class CalendarAdapter { - - /** @var \OCP\IDBConnection */ - protected $dbConnection; - - /** @var string */ - private $sourceCalendarTable; - - /** @var string */ - private $sourceCalObjTable; - - /** - * @param IDBConnection $dbConnection - * @param string $sourceCalendarTable - * @param string $sourceCalObjTable - */ - function __construct(IDBConnection $dbConnection, - $sourceCalendarTable = 'clndr_calendars', - $sourceCalObjTable = 'clndr_objects') { - $this->dbConnection = $dbConnection; - $this->sourceCalendarTable = $sourceCalendarTable; - $this->sourceCalObjTable = $sourceCalObjTable; - } - - /** - * @param string $user - * @param \Closure $callBack - */ - public function foreachCalendar($user, \Closure $callBack) { - // get all calendars of that user - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceCalendarTable) - ->where($query->expr()->eq('userid', $query->createNamedParameter($user))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - public function setup() { - if (!$this->dbConnection->tableExists($this->sourceCalendarTable)) { - throw new \DomainException('Calendar tables are missing. Nothing to do.'); - } - } - - /** - * @param int $calendarId - * @param \Closure $callBack - */ - public function foreachCalendarObject($calendarId, \Closure $callBack) { - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceCalObjTable) - ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - /** - * @param int $addressBookId - * @return array - */ - public function getShares($addressBookId) { - $query = $this->dbConnection->getQueryBuilder(); - $shares = $query->select('*')->from('share') - ->where($query->expr()->eq('item_source', $query->createNamedParameter($addressBookId))) - ->andWhere($query->expr()->eq('item_type', $query->expr()->literal('calendar'))) - ->andWhere($query->expr()->in('share_type', [ $query->expr()->literal(0), $query->expr()->literal(1)])) - ->execute() - ->fetchAll(); - - return $shares; - } -} diff --git a/apps/dav/lib/migration/migrateaddressbooks.php b/apps/dav/lib/migration/migrateaddressbooks.php deleted file mode 100644 index 7e1f47ea75e..00000000000 --- a/apps/dav/lib/migration/migrateaddressbooks.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCA\DAV\CardDAV\AddressBook; -use OCA\DAV\CardDAV\CardDavBackend; -use OCP\ILogger; -use Sabre\CardDAV\Plugin; -use Symfony\Component\Console\Output\OutputInterface; - -class MigrateAddressbooks { - - /** @var AddressBookAdapter */ - protected $adapter; - - /** @var CardDavBackend */ - private $backend; - - /** @var ILogger */ - private $logger; - - /** @var OutputInterface */ - private $consoleOutput; - - - /** - * @param AddressBookAdapter $adapter - * @param CardDavBackend $backend - */ - function __construct(AddressBookAdapter $adapter, - CardDavBackend $backend, - ILogger $logger, - OutputInterface $consoleOutput = null - ) { - $this->adapter = $adapter; - $this->backend = $backend; - $this->logger = $logger; - $this->consoleOutput = $consoleOutput; - } - - /** - * @param string $user - */ - public function migrateForUser($user) { - - $this->adapter->foreachBook($user, function($book) use ($user) { - $principal = "principals/users/$user"; - $knownBooks = $this->backend->getAddressBooksByUri($principal, $book['uri']); - if (!is_null($knownBooks)) { - return; - } - - $newId = $this->backend->createAddressBook($principal, $book['uri'], [ - '{DAV:}displayname' => $book['displayname'], - '{' . Plugin::NS_CARDDAV . '}addressbook-description' => $book['description'] - ]); - - $this->migrateBook($book['id'], $newId); - $this->migrateShares($book['id'], $newId); - }); - } - - public function setup() { - $this->adapter->setup(); - } - - /** - * @param int $addressBookId - * @param int $newAddressBookId - */ - private function migrateBook($addressBookId, $newAddressBookId) { - $this->adapter->foreachCard($addressBookId, function($card) use ($newAddressBookId) { - try { - $this->backend->createCard($newAddressBookId, $card['uri'], $card['carddata']); - } catch (\Exception $ex) { - $eventId = $card['id']; - $addressBookId = $card['addressbookid']; - $msg = "One event could not be migrated. (id: $eventId, addressbookid: $addressBookId)"; - $this->logger->logException($ex, ['app' => 'dav', 'message' => $msg]); - if (!is_null($this->consoleOutput)) { - $this->consoleOutput->writeln($msg); - } - } - }); - } - - /** - * @param int $addressBookId - * @param int $newAddressBookId - */ - private function migrateShares($addressBookId, $newAddressBookId) { - $shares =$this->adapter->getShares($addressBookId); - if (empty($shares)) { - return; - } - - $add = array_map(function($s) { - $prefix = 'principal:principals/users/'; - if ((int)$s['share_type'] === 1) { - $prefix = 'principal:principals/groups/'; - } - return [ - 'href' => $prefix . $s['share_with'], - 'readOnly' => !((int)$s['permissions'] === 31) - ]; - }, $shares); - - $newAddressBook = $this->backend->getAddressBookById($newAddressBookId); - $book = new AddressBook($this->backend, $newAddressBook); - $this->backend->updateShares($book, $add, []); - } -} diff --git a/apps/dav/lib/migration/migratecalendars.php b/apps/dav/lib/migration/migratecalendars.php deleted file mode 100644 index 3c1487761c2..00000000000 --- a/apps/dav/lib/migration/migratecalendars.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCA\DAV\CalDAV\CalDavBackend; -use OCA\DAV\CalDAV\Calendar; -use OCP\ILogger; -use Symfony\Component\Console\Output\OutputInterface; - -class MigrateCalendars { - - /** @var CalendarAdapter */ - protected $adapter; - - /** @var CalDavBackend */ - private $backend; - - /** @var ILogger */ - private $logger; - - /** @var OutputInterface */ - private $consoleOutput; - - /** - * @param CalendarAdapter $adapter - * @param CalDavBackend $backend - */ - function __construct(CalendarAdapter $adapter, - CalDavBackend $backend, - ILogger $logger, - OutputInterface $consoleOutput = null - ) { - $this->adapter = $adapter; - $this->backend = $backend; - $this->logger = $logger; - $this->consoleOutput = $consoleOutput; - } - - /** - * @param string $user - */ - public function migrateForUser($user) { - - $this->adapter->foreachCalendar($user, function($calendar) use ($user) { - $principal = "principals/users/$user"; - $calendarByUri = $this->backend->getCalendarByUri($principal, $calendar['uri']); - if (!is_null($calendarByUri)) { - return; - } - - $newId = $this->backend->createCalendar($principal, $calendar['uri'], [ - '{DAV:}displayname' => $calendar['displayname'], - '{urn:ietf:params:xml:ns:caldav}calendar-description' => $calendar['displayname'], - '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $calendar['timezone'], - '{http://apple.com/ns/ical/}calendar-order' => $calendar['calendarorder'], - '{http://apple.com/ns/ical/}calendar-color' => $calendar['calendarcolor'], - ]); - - $this->migrateCalendar($calendar['id'], $newId); - $this->migrateShares($calendar['id'], $newId); - }); - } - - public function setup() { - $this->adapter->setup(); - } - - /** - * @param int $calendarId - * @param int $newCalendarId - */ - private function migrateCalendar($calendarId, $newCalendarId) { - $this->adapter->foreachCalendarObject($calendarId, function($calObject) use ($newCalendarId) { - try { - $this->backend->createCalendarObject($newCalendarId, $calObject['uri'], $calObject['calendardata']); - } catch (\Exception $ex) { - $eventId = $calObject['id']; - $calendarId = $calObject['calendarId']; - $msg = "One event could not be migrated. (id: $eventId, calendarid: $calendarId)"; - $this->logger->logException($ex, ['app' => 'dav', 'message' => $msg]); - if (!is_null($this->consoleOutput)) { - $this->consoleOutput->writeln($msg); - } - } - }); - } - - /** - * @param int $calendarId - * @param int $newCalendarId - */ - private function migrateShares($calendarId, $newCalendarId) { - $shares =$this->adapter->getShares($calendarId); - if (empty($shares)) { - return; - } - - $add = array_map(function($s) { - $prefix = 'principal:principals/users/'; - if ((int)$s['share_type'] === 1) { - $prefix = 'principal:principals/groups/'; - } - return [ - 'href' => $prefix . $s['share_with'], - 'readOnly' => !((int)$s['permissions'] === 31) - ]; - }, $shares); - - $newCalendar = $this->backend->getCalendarById($newCalendarId); - $calendar = new Calendar($this->backend, $newCalendar); - $this->backend->updateShares($calendar, $add, []); - } -} diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php index ea796c09175..b6e1747e990 100644 --- a/apps/dav/lib/rootcollection.php +++ b/apps/dav/lib/rootcollection.php @@ -89,6 +89,9 @@ class RootCollection extends SimpleCollection { $systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system'); $systemAddressBookRoot->disableListing = $disableListing; + $uploadCollection = new Upload\RootCollection($userPrincipalBackend, 'principals/users'); + $uploadCollection->disableListing = $disableListing; + $children = [ new SimpleCollection('principals', [ $userPrincipals, @@ -102,6 +105,7 @@ class RootCollection extends SimpleCollection { $systemTagCollection, $systemTagRelationsCollection, $commentsCollection, + $uploadCollection, ]; parent::__construct('root', $children); diff --git a/apps/dav/lib/upload/assemblystream.php b/apps/dav/lib/upload/assemblystream.php new file mode 100644 index 00000000000..4b80a591ce4 --- /dev/null +++ b/apps/dav/lib/upload/assemblystream.php @@ -0,0 +1,234 @@ +<?php + +namespace OCA\DAV\Upload; + +use Sabre\DAV\IFile; + +/** + * Class AssemblyStream + * + * The assembly stream is a virtual stream that wraps multiple chunks. + * Reading from the stream transparently accessed the underlying chunks and + * give a representation as if they were already merged together. + * + * @package OCA\DAV\Upload + */ +class AssemblyStream implements \Icewind\Streams\File { + + /** @var resource */ + private $context; + + /** @var IFile[] */ + private $nodes; + + /** @var int */ + private $pos = 0; + + /** @var array */ + private $sortedNodes; + + /** @var int */ + private $size; + + /** + * @param string $path + * @param string $mode + * @param int $options + * @param string &$opened_path + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path) { + $this->loadContext('assembly'); + + // sort the nodes + $nodes = $this->nodes; + // http://stackoverflow.com/a/10985500 + @usort($nodes, function(IFile $a, IFile $b) { + return strcmp($a->getName(), $b->getName()); + }); + $this->nodes = $nodes; + + // build additional information + $this->sortedNodes = []; + $start = 0; + foreach($this->nodes as $node) { + $size = $node->getSize(); + $name = $node->getName(); + $this->sortedNodes[$name] = ['node' => $node, 'start' => $start, 'end' => $start + $size]; + $start += $size; + $this->size = $start; + } + return true; + } + + /** + * @param string $offset + * @param int $whence + * @return bool + */ + public function stream_seek($offset, $whence = SEEK_SET) { + return false; + } + + /** + * @return int + */ + public function stream_tell() { + return $this->pos; + } + + /** + * @param int $count + * @return string + */ + public function stream_read($count) { + + list($node, $posInNode) = $this->getNodeForPosition($this->pos); + if (is_null($node)) { + return null; + } + $stream = $this->getStream($node); + + fseek($stream, $posInNode); + $data = fread($stream, $count); + $read = strlen($data); + + // update position + $this->pos += $read; + return $data; + } + + /** + * @param string $data + * @return int + */ + public function stream_write($data) { + return false; + } + + /** + * @param int $option + * @param int $arg1 + * @param int $arg2 + * @return bool + */ + public function stream_set_option($option, $arg1, $arg2) { + return false; + } + + /** + * @param int $size + * @return bool + */ + public function stream_truncate($size) { + return false; + } + + /** + * @return array + */ + public function stream_stat() { + return []; + } + + /** + * @param int $operation + * @return bool + */ + public function stream_lock($operation) { + return false; + } + + /** + * @return bool + */ + public function stream_flush() { + return false; + } + + /** + * @return bool + */ + public function stream_eof() { + return $this->pos >= $this->size; + } + + /** + * @return bool + */ + public function stream_close() { + return true; + } + + + /** + * Load the source from the stream context and return the context options + * + * @param string $name + * @return array + * @throws \Exception + */ + protected function loadContext($name) { + $context = stream_context_get_options($this->context); + if (isset($context[$name])) { + $context = $context[$name]; + } else { + throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set'); + } + if (isset($context['nodes']) and is_array($context['nodes'])) { + $this->nodes = $context['nodes']; + } else { + throw new \BadMethodCallException('Invalid context, nodes not set'); + } + return $context; + } + + /** + * @param IFile[] $nodes + * @return resource + * + * @throws \BadMethodCallException + */ + public static function wrap(array $nodes) { + $context = stream_context_create([ + 'assembly' => [ + 'nodes' => $nodes] + ]); + stream_wrapper_register('assembly', '\OCA\DAV\Upload\AssemblyStream'); + try { + $wrapped = fopen('assembly://', 'r', null, $context); + } catch (\BadMethodCallException $e) { + stream_wrapper_unregister('assembly'); + throw $e; + } + stream_wrapper_unregister('assembly'); + return $wrapped; + } + + /** + * @param $pos + * @return IFile | null + */ + private function getNodeForPosition($pos) { + foreach($this->sortedNodes as $node) { + if ($pos >= $node['start'] && $pos < $node['end']) { + return [$node['node'], $pos - $node['start']]; + } + } + return null; + } + + /** + * @param IFile $node + * @return resource + */ + private function getStream(IFile $node) { + $data = $node->get(); + if (is_resource($data)) { + return $data; + } + + return fopen('data://text/plain,' . $data,'r'); + } + +} diff --git a/apps/dav/lib/upload/futurefile.php b/apps/dav/lib/upload/futurefile.php new file mode 100644 index 00000000000..aca81afc055 --- /dev/null +++ b/apps/dav/lib/upload/futurefile.php @@ -0,0 +1,103 @@ +<?php + +namespace OCA\DAV\Upload; + +use OCA\DAV\Connector\Sabre\Directory; +use OCA\DAV\Upload\AssemblyStream; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\IFile; + +/** + * Class FutureFile + * + * The FutureFile is a SabreDav IFile which connects the chunked upload directory + * with the AssemblyStream, who does the final assembly job + * + * @package OCA\DAV\Upload + */ +class FutureFile implements \Sabre\DAV\IFile { + + /** @var Directory */ + private $root; + /** @var string */ + private $name; + + /** + * @param Directory $root + * @param string $name + */ + function __construct(Directory $root, $name) { + $this->root = $root; + $this->name = $name; + } + + /** + * @inheritdoc + */ + function put($data) { + throw new Forbidden('Permission denied to put into this file'); + } + + /** + * @inheritdoc + */ + function get() { + $nodes = $this->root->getChildren(); + return AssemblyStream::wrap($nodes); + } + + /** + * @inheritdoc + */ + function getContentType() { + return 'application/octet-stream'; + } + + /** + * @inheritdoc + */ + function getETag() { + return $this->root->getETag(); + } + + /** + * @inheritdoc + */ + function getSize() { + $children = $this->root->getChildren(); + $sizes = array_map(function($node) { + /** @var IFile $node */ + return $node->getSize(); + }, $children); + + return array_sum($sizes); + } + + /** + * @inheritdoc + */ + function delete() { + $this->root->delete(); + } + + /** + * @inheritdoc + */ + function getName() { + return $this->name; + } + + /** + * @inheritdoc + */ + function setName($name) { + throw new Forbidden('Permission denied to rename this file'); + } + + /** + * @inheritdoc + */ + function getLastModified() { + return $this->root->getLastModified(); + } +} diff --git a/apps/dav/lib/upload/rootcollection.php b/apps/dav/lib/upload/rootcollection.php new file mode 100644 index 00000000000..673a3734318 --- /dev/null +++ b/apps/dav/lib/upload/rootcollection.php @@ -0,0 +1,23 @@ +<?php + +namespace OCA\DAV\Upload; + +use Sabre\DAVACL\AbstractPrincipalCollection; + +class RootCollection extends AbstractPrincipalCollection { + + /** + * @inheritdoc + */ + function getChildForPrincipal(array $principalInfo) { + return new UploadHome($principalInfo); + } + + /** + * @inheritdoc + */ + function getName() { + return 'uploads'; + } + +} diff --git a/apps/dav/lib/upload/uploadfolder.php b/apps/dav/lib/upload/uploadfolder.php new file mode 100644 index 00000000000..01fbf1f8dc9 --- /dev/null +++ b/apps/dav/lib/upload/uploadfolder.php @@ -0,0 +1,61 @@ +<?php + +namespace OCA\DAV\Upload; + +use OCA\DAV\Connector\Sabre\Directory; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\ICollection; + +class UploadFolder implements ICollection { + + private $node; + + function __construct(Directory $node) { + $this->node = $node; + } + + function createFile($name, $data = null) { + // TODO: verify name - should be a simple number + $this->node->createFile($name, $data); + } + + function createDirectory($name) { + throw new Forbidden('Permission denied to create file (filename ' . $name . ')'); + } + + function getChild($name) { + if ($name === '.file') { + return new FutureFile($this->node, '.file'); + } + return $this->node->getChild($name); + } + + function getChildren() { + $children = $this->node->getChildren(); + $children[] = new FutureFile($this->node, '.file'); + return $children; + } + + function childExists($name) { + if ($name === '.file') { + return true; + } + return $this->node->childExists($name); + } + + function delete() { + $this->node->delete(); + } + + function getName() { + return $this->node->getName(); + } + + function setName($name) { + throw new Forbidden('Permission denied to rename this folder'); + } + + function getLastModified() { + return $this->node->getLastModified(); + } +} diff --git a/apps/dav/lib/upload/uploadhome.php b/apps/dav/lib/upload/uploadhome.php new file mode 100644 index 00000000000..ae4dcfa4931 --- /dev/null +++ b/apps/dav/lib/upload/uploadhome.php @@ -0,0 +1,74 @@ +<?php + +namespace OCA\DAV\Upload; + +use OC\Files\Filesystem; +use OC\Files\View; +use OCA\DAV\Connector\Sabre\Directory; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\ICollection; + +class UploadHome implements ICollection { + /** + * FilesHome constructor. + * + * @param array $principalInfo + */ + public function __construct($principalInfo) { + $this->principalInfo = $principalInfo; + } + + function createFile($name, $data = null) { + throw new Forbidden('Permission denied to create file (filename ' . $name . ')'); + } + + function createDirectory($name) { + $this->impl()->createDirectory($name); + } + + function getChild($name) { + return new UploadFolder($this->impl()->getChild($name)); + } + + function getChildren() { + return array_map(function($node) { + return new UploadFolder($node); + }, $this->impl()->getChildren()); + } + + function childExists($name) { + return !is_null($this->getChild($name)); + } + + function delete() { + $this->impl()->delete(); + } + + function getName() { + return 'uploads'; + } + + function setName($name) { + throw new Forbidden('Permission denied to rename this folder'); + } + + function getLastModified() { + return $this->impl()->getLastModified(); + } + + /** + * @return Directory + */ + private function impl() { + $rootView = new View(); + $user = \OC::$server->getUserSession()->getUser(); + Filesystem::initMountPoints($user->getUID()); + if (!$rootView->file_exists('/' . $user->getUID() . '/uploads')) { + $rootView->mkdir('/' . $user->getUID() . '/uploads'); + } + $view = new View('/' . $user->getUID() . '/uploads'); + $rootInfo = $view->getFileInfo(''); + $impl = new Directory($view, $rootInfo); + return $impl; + } +} diff --git a/apps/dav/tests/unit/caldav/caldavbackendtest.php b/apps/dav/tests/unit/caldav/caldavbackendtest.php index 87a700a473d..a4a19f5bd3e 100644 --- a/apps/dav/tests/unit/caldav/caldavbackendtest.php +++ b/apps/dav/tests/unit/caldav/caldavbackendtest.php @@ -136,14 +136,23 @@ class CalDavBackendTest extends TestCase { */ public function testCalendarSharing($userCanRead, $userCanWrite, $groupCanRead, $groupCanWrite, $add) { + $l10n = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + $l10n + ->expects($this->any()) + ->method('t') + ->will($this->returnCallback(function ($text, $parameters = array()) { + return vsprintf($text, $parameters); + })); + $calendarId = $this->createTestCalendar(); $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); $this->assertEquals(1, count($books)); - $calendar = new Calendar($this->backend, $books[0]); + $calendar = new Calendar($this->backend, $books[0], $l10n); $this->backend->updateShares($calendar, $add, []); $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER1); $this->assertEquals(1, count($books)); - $calendar = new Calendar($this->backend, $books[0]); + $calendar = new Calendar($this->backend, $books[0], $l10n); $acl = $calendar->getACL(); $this->assertAcl(self::UNIT_TEST_USER, '{DAV:}read', $acl); $this->assertAcl(self::UNIT_TEST_USER, '{DAV:}write', $acl); diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index 9e0c3c6c7e4..812e0074d15 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -23,11 +23,27 @@ namespace OCA\DAV\Tests\Unit\CalDAV; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; +use OCP\IL10N; use Sabre\DAV\PropPatch; use Test\TestCase; class CalendarTest extends TestCase { + /** @var IL10N */ + private $l10n; + + public function setUp() { + parent::setUp(); + $this->l10n = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + $this->l10n + ->expects($this->any()) + ->method('t') + ->will($this->returnCallback(function ($text, $parameters = array()) { + return vsprintf($text, $parameters); + })); + } + public function testDelete() { /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); @@ -41,7 +57,7 @@ class CalendarTest extends TestCase { 'id' => 666, 'uri' => 'cal', ]; - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); $c->delete(); } @@ -61,7 +77,7 @@ class CalendarTest extends TestCase { 'id' => 666, 'uri' => 'cal', ]; - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); $c->delete(); } @@ -93,7 +109,7 @@ class CalendarTest extends TestCase { 'id' => 666, 'uri' => 'default' ]; - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); if ($throws) { $this->setExpectedException('\Sabre\DAV\Exception\Forbidden'); @@ -122,7 +138,7 @@ class CalendarTest extends TestCase { if ($hasOwnerSet) { $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1'; } - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); $acl = $c->getACL(); $childAcl = $c->getChildACL(); diff --git a/apps/dav/tests/unit/connector/sabre/filesplugin.php b/apps/dav/tests/unit/connector/sabre/filesplugin.php index fb08ee170c4..63ee5a53c17 100644 --- a/apps/dav/tests/unit/connector/sabre/filesplugin.php +++ b/apps/dav/tests/unit/connector/sabre/filesplugin.php @@ -23,6 +23,9 @@ namespace OCA\DAV\Tests\Unit\Connector\Sabre; use OCP\Files\StorageNotAvailableException; +use Sabre\DAV\PropFind; +use Sabre\DAV\PropPatch; +use Test\TestCase; /** * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com> @@ -30,7 +33,7 @@ use OCP\Files\StorageNotAvailableException; * later. * See the COPYING-README file. */ -class FilesPlugin extends \Test\TestCase { +class FilesPlugin extends TestCase { const GETETAG_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::GETETAG_PROPERTYNAME; const FILEID_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::FILEID_PROPERTYNAME; const INTERNAL_FILEID_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::INTERNAL_FILEID_PROPERTYNAME; @@ -42,12 +45,12 @@ class FilesPlugin extends \Test\TestCase { const OWNER_DISPLAY_NAME_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME; /** - * @var \Sabre\DAV\Server + * @var \Sabre\DAV\Server | \PHPUnit_Framework_MockObject_MockObject */ private $server; /** - * @var \Sabre\DAV\Tree + * @var \Sabre\DAV\Tree | \PHPUnit_Framework_MockObject_MockObject */ private $tree; @@ -57,7 +60,7 @@ class FilesPlugin extends \Test\TestCase { private $plugin; /** - * @var \OC\Files\View + * @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject */ private $view; @@ -79,6 +82,7 @@ class FilesPlugin extends \Test\TestCase { /** * @param string $class + * @return \PHPUnit_Framework_MockObject_MockObject */ private function createTestNode($class) { $node = $this->getMockBuilder($class) @@ -111,9 +115,10 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPropertiesForFile() { + /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::GETETAG_PROPERTYNAME, @@ -165,11 +170,12 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPropertiesForFileHome() { + /** @var \OCA\DAV\Files\FilesHome | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->getMockBuilder('\OCA\DAV\Files\FilesHome') ->disableOriginalConstructor() ->getMock(); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::GETETAG_PROPERTYNAME, @@ -214,9 +220,10 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPropertiesStorageNotAvailable() { + /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::DOWNLOADURL_PROPERTYNAME, @@ -240,7 +247,7 @@ class FilesPlugin extends \Test\TestCase { $this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view, true); $this->plugin->initialize($this->server); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', [ self::PERMISSIONS_PROPERTYNAME, @@ -248,6 +255,7 @@ class FilesPlugin extends \Test\TestCase { 0 ); + /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); $node->expects($this->any()) ->method('getDavPermissions') @@ -262,9 +270,10 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPropertiesForDirectory() { + /** @var \OCA\DAV\Connector\Sabre\Directory | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\Directory'); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::GETETAG_PROPERTYNAME, @@ -308,7 +317,7 @@ class FilesPlugin extends \Test\TestCase { ->will($this->returnValue(true)); // properties to set - $propPatch = new \Sabre\DAV\PropPatch(array( + $propPatch = new PropPatch(array( self::GETETAG_PROPERTYNAME => 'newetag', self::LASTMODIFIED_PROPERTYNAME => $testDate )); @@ -328,9 +337,7 @@ class FilesPlugin extends \Test\TestCase { } public function testUpdatePropsForbidden() { - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - - $propPatch = new \Sabre\DAV\PropPatch(array( + $propPatch = new PropPatch(array( self::OWNER_ID_PROPERTYNAME => 'user2', self::OWNER_DISPLAY_NAME_PROPERTYNAME => 'User Two', self::FILEID_PROPERTYNAME => 12345, diff --git a/apps/dav/tests/unit/migration/addressbookadaptertest.php b/apps/dav/tests/unit/migration/addressbookadaptertest.php deleted file mode 100644 index e6e57049a93..00000000000 --- a/apps/dav/tests/unit/migration/addressbookadaptertest.php +++ /dev/null @@ -1,129 +0,0 @@ -<?php -/** - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\DAV\Tests\Unit\Migration; - -use DomainException; -use OCA\Dav\Migration\AddressBookAdapter; -use OCP\IDBConnection; -use Test\TestCase; - -/** - * Class AddressbookAdapterTest - * - * @group DB - * - * @package OCA\DAV\Tests\Unit\Migration - */ -class AddressbookAdapterTest extends TestCase { - - /** @var IDBConnection */ - private $db; - /** @var AddressBookAdapter */ - private $adapter; - /** @var array */ - private $books = []; - /** @var array */ - private $cards = []; - - public function setUp() { - parent::setUp(); - $this->db = \OC::$server->getDatabaseConnection(); - - $manager = new \OC\DB\MDB2SchemaManager($this->db); - $manager->createDbFromStructure(__DIR__ . '/contacts_schema.xml'); - - $this->adapter = new AddressBookAdapter($this->db); - } - - public function tearDown() { - $this->db->dropTable('contacts_addressbooks'); - $this->db->dropTable('contacts_cards'); - parent::tearDown(); - } - - /** - * @expectedException DomainException - */ - public function testOldTablesDoNotExist() { - $adapter = new AddressBookAdapter(\OC::$server->getDatabaseConnection(), 'crazy_table_that_does_no_exist'); - $adapter->setup(); - } - - public function test() { - - // insert test data - $builder = $this->db->getQueryBuilder(); - $builder->insert('contacts_addressbooks') - ->values([ - 'userid' => $builder->createNamedParameter('test-user-666'), - 'displayname' => $builder->createNamedParameter('Display Name'), - 'uri' => $builder->createNamedParameter('contacts'), - 'description' => $builder->createNamedParameter('An address book for testing'), - 'ctag' => $builder->createNamedParameter('112233'), - 'active' => $builder->createNamedParameter('1') - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('contacts_cards') - ->values([ - 'addressbookid' => $builder->createNamedParameter(6666), - 'fullname' => $builder->createNamedParameter('Full Name'), - 'carddata' => $builder->createNamedParameter('datadatadata'), - 'uri' => $builder->createNamedParameter('some-card.vcf'), - 'lastmodified' => $builder->createNamedParameter('112233'), - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('share') - ->values([ - 'share_type' => $builder->createNamedParameter(1), - 'share_with' => $builder->createNamedParameter('user01'), - 'uid_owner' => $builder->createNamedParameter('user02'), - 'item_type' => $builder->createNamedParameter('addressbook'), - 'item_source' => $builder->createNamedParameter(6666), - 'item_target' => $builder->createNamedParameter('Contacts (user02)'), - ]) - ->execute(); - - // test the adapter - $this->adapter->foreachBook('test-user-666', function($row) { - $this->books[] = $row; - }); - $this->assertArrayHasKey('id', $this->books[0]); - $this->assertEquals('test-user-666', $this->books[0]['userid']); - $this->assertEquals('Display Name', $this->books[0]['displayname']); - $this->assertEquals('contacts', $this->books[0]['uri']); - $this->assertEquals('An address book for testing', $this->books[0]['description']); - $this->assertEquals('112233', $this->books[0]['ctag']); - - $this->adapter->foreachCard(6666, function($row) { - $this->cards[]= $row; - }); - $this->assertArrayHasKey('id', $this->cards[0]); - $this->assertEquals(6666, $this->cards[0]['addressbookid']); - - // test getShares - $shares = $this->adapter->getShares(6666); - $this->assertEquals(1, count($shares)); - - } - -} diff --git a/apps/dav/tests/unit/migration/calendar_schema.xml b/apps/dav/tests/unit/migration/calendar_schema.xml deleted file mode 100644 index 6c88b596a3f..00000000000 --- a/apps/dav/tests/unit/migration/calendar_schema.xml +++ /dev/null @@ -1,191 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<database> - - <name>*dbname*</name> - <create>true</create> - <overwrite>false</overwrite> - - <charset>utf8</charset> - - <table> - - <name>*dbprefix*clndr_objects</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>calendarid</name> - <type>integer</type> - <default></default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>objecttype</name> - <type>text</type> - <default></default> - <notnull>true</notnull> - <length>40</length> - </field> - - <field> - <name>startdate</name> - <type>timestamp</type> - <default>1970-01-01 00:00:00</default> - <notnull>false</notnull> - </field> - - <field> - <name>enddate</name> - <type>timestamp</type> - <default>1970-01-01 00:00:00</default> - <notnull>false</notnull> - </field> - - <field> - <name>repeating</name> - <type>integer</type> - <default></default> - <notnull>false</notnull> - <length>4</length> - </field> - - <field> - <name>summary</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>calendardata</name> - <type>clob</type> - <notnull>false</notnull> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>lastmodified</name> - <type>integer</type> - <default></default> - <notnull>false</notnull> - <length>4</length> - </field> - - </declaration> - - </table> - - <table> - - <name>*dbprefix*clndr_calendars</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>userid</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>displayname</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>100</length> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>active</name> - <type>integer</type> - <default>1</default> - <notnull>true</notnull> - <length>4</length> - </field> - - <field> - <name>ctag</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>calendarorder</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>calendarcolor</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>10</length> - </field> - - <field> - <name>timezone</name> - <type>clob</type> - <notnull>false</notnull> - </field> - - <field> - <name>components</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>100</length> - </field> - - </declaration> - - </table> - -</database> diff --git a/apps/dav/tests/unit/migration/calendaradaptertest.php b/apps/dav/tests/unit/migration/calendaradaptertest.php deleted file mode 100644 index f92774ef6ad..00000000000 --- a/apps/dav/tests/unit/migration/calendaradaptertest.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\DAV\Tests\Unit\Migration; - -use DomainException; -use OCA\Dav\Migration\AddressBookAdapter; -use OCA\Dav\Migration\CalendarAdapter; -use OCP\IDBConnection; -use Test\TestCase; - -/** - * Class CalendarAdapterTest - * - * @group DB - * - * @package OCA\DAV\Tests\Unit\Migration - */ -class CalendarAdapterTest extends TestCase { - - /** @var IDBConnection */ - private $db; - /** @var CalendarAdapter */ - private $adapter; - /** @var array */ - private $cals = []; - /** @var array */ - private $calObjs = []; - - public function setUp() { - parent::setUp(); - $this->db = \OC::$server->getDatabaseConnection(); - - $manager = new \OC\DB\MDB2SchemaManager($this->db); - $manager->createDbFromStructure(__DIR__ . '/calendar_schema.xml'); - - $this->adapter = new CalendarAdapter($this->db); - } - - public function tearDown() { - $this->db->dropTable('clndr_calendars'); - $this->db->dropTable('clndr_objects'); - parent::tearDown(); - } - - /** - * @expectedException DomainException - */ - public function testOldTablesDoNotExist() { - $adapter = new AddressBookAdapter(\OC::$server->getDatabaseConnection(), 'crazy_table_that_does_no_exist'); - $adapter->setup(); - } - - public function test() { - - // insert test data - $builder = $this->db->getQueryBuilder(); - $builder->insert('clndr_calendars') - ->values([ - 'userid' => $builder->createNamedParameter('test-user-666'), - 'displayname' => $builder->createNamedParameter('Display Name'), - 'uri' => $builder->createNamedParameter('events'), - 'ctag' => $builder->createNamedParameter('112233'), - 'active' => $builder->createNamedParameter('1') - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('clndr_objects') - ->values([ - 'calendarid' => $builder->createNamedParameter(6666), - 'objecttype' => $builder->createNamedParameter('VEVENT'), - 'startdate' => $builder->createNamedParameter(new \DateTime(), 'datetime'), - 'enddate' => $builder->createNamedParameter(new \DateTime(), 'datetime'), - 'repeating' => $builder->createNamedParameter(0), - 'summary' => $builder->createNamedParameter('Something crazy will happen'), - 'uri' => $builder->createNamedParameter('event.ics'), - 'lastmodified' => $builder->createNamedParameter('112233'), - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('share') - ->values([ - 'share_type' => $builder->createNamedParameter(1), - 'share_with' => $builder->createNamedParameter('user01'), - 'uid_owner' => $builder->createNamedParameter('user02'), - 'item_type' => $builder->createNamedParameter('calendar'), - 'item_source' => $builder->createNamedParameter(6666), - 'item_target' => $builder->createNamedParameter('Contacts (user02)'), - ]) - ->execute(); - - // test the adapter - $this->adapter->foreachCalendar('test-user-666', function($row) { - $this->cals[] = $row; - }); - $this->assertArrayHasKey('id', $this->cals[0]); - $this->assertEquals('test-user-666', $this->cals[0]['userid']); - $this->assertEquals('Display Name', $this->cals[0]['displayname']); - $this->assertEquals('events', $this->cals[0]['uri']); - $this->assertEquals('112233', $this->cals[0]['ctag']); - - $this->adapter->foreachCalendarObject(6666, function($row) { - $this->calObjs[]= $row; - }); - $this->assertArrayHasKey('id', $this->calObjs[0]); - $this->assertEquals(6666, $this->calObjs[0]['calendarid']); - - // test getShares - $shares = $this->adapter->getShares(6666); - $this->assertEquals(1, count($shares)); - - } - -} diff --git a/apps/dav/tests/unit/migration/contacts_schema.xml b/apps/dav/tests/unit/migration/contacts_schema.xml deleted file mode 100644 index 51836a1e0c6..00000000000 --- a/apps/dav/tests/unit/migration/contacts_schema.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<database> - - <name>*dbname*</name> - <create>true</create> - <overwrite>false</overwrite> - <charset>utf8</charset> - <table> - - <name>*dbprefix*contacts_addressbooks</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>userid</name> - <type>text</type> - <default></default> - <notnull>true</notnull> - <length>255</length> - </field> - - <field> - <name>displayname</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>200</length> - </field> - - <field> - <name>description</name> - <type>text</type> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>ctag</name> - <type>integer</type> - <default>1</default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>active</name> - <type>integer</type> - <default>1</default> - <notnull>true</notnull> - <length>4</length> - </field> - - <index> - <name>c_addressbook_userid_index</name> - <field> - <name>userid</name> - <sorting>ascending</sorting> - </field> - </index> - </declaration> - - </table> - - <table> - - <name>*dbprefix*contacts_cards</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>addressbookid</name> - <type>integer</type> - <default></default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>fullname</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>carddata</name> - <type>clob</type> - <notnull>false</notnull> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>200</length> - </field> - - <field> - <name>lastmodified</name> - <type>integer</type> - <default></default> - <notnull>false</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - - <index> - <name>c_addressbookid_index</name> - <field> - <name>addressbookid</name> - <sorting>ascending</sorting> - </field> - </index> - </declaration> - - </table> - -</database> diff --git a/apps/dav/tests/unit/migration/migrateaddressbooktest.php b/apps/dav/tests/unit/migration/migrateaddressbooktest.php deleted file mode 100644 index 31cb16265c0..00000000000 --- a/apps/dav/tests/unit/migration/migrateaddressbooktest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\DAV\Tests\Unit\Migration; - -use OCA\DAV\CardDAV\CardDavBackend; -use OCA\Dav\Migration\AddressBookAdapter; -use OCP\ILogger; -use Test\TestCase; - -class MigrateAddressbookTest extends TestCase { - - public function testMigration() { - /** @var AddressBookAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ - $adapter = $this->mockAdapter([ - ['share_type' => '1', 'share_with' => 'users', 'permissions' => '31'], - ['share_type' => '2', 'share_with' => 'adam', 'permissions' => '1'], - ]); - - /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ - $cardDav = $this->getMockBuilder('\OCA\Dav\CardDAV\CardDAVBackend')->disableOriginalConstructor()->getMock(); - $cardDav->expects($this->any())->method('createAddressBook')->willReturn(666); - $cardDav->expects($this->any())->method('getAddressBookById')->willReturn([]); - $cardDav->expects($this->once())->method('createAddressBook')->with('principals/users/test01', 'test_contacts'); - $cardDav->expects($this->once())->method('createCard')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', 'BEGIN:VCARD'); - $cardDav->expects($this->once())->method('updateShares')->with($this->anything(), [ - ['href' => 'principal:principals/groups/users', 'readOnly' => false], - ['href' => 'principal:principals/users/adam', 'readOnly' => true] - ]); - /** @var ILogger $logger */ - $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); - - $m = new \OCA\Dav\Migration\MigrateAddressbooks($adapter, $cardDav, $logger, null); - $m->migrateForUser('test01'); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function mockAdapter($shares = []) { - $adapter = $this->getMockBuilder('\OCA\Dav\Migration\AddressBookAdapter')->disableOriginalConstructor()->getMock(); - $adapter->expects($this->any())->method('foreachBook')->willReturnCallback(function ($user, \Closure $callBack) { - $callBack([ - 'id' => 0, - 'userid' => $user, - 'displayname' => 'Test Contacts', - 'uri' => 'test_contacts', - 'description' => 'Contacts to test with', - 'ctag' => 1234567890, - 'active' => 1 - ]); - }); - $adapter->expects($this->any())->method('foreachCard')->willReturnCallback(function ($addressBookId, \Closure $callBack) { - $callBack([ - 'userid' => $addressBookId, - 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', - 'carddata' => 'BEGIN:VCARD' - ]); - }); - $adapter->expects($this->any())->method('getShares')->willReturn($shares); - return $adapter; - } - -} diff --git a/apps/dav/tests/unit/migration/migratecalendartest.php b/apps/dav/tests/unit/migration/migratecalendartest.php deleted file mode 100644 index e62970aef34..00000000000 --- a/apps/dav/tests/unit/migration/migratecalendartest.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php -/** - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\DAV\Tests\Unit\Migration; - -use OCA\DAV\CalDAV\CalDavBackend; -use OCA\Dav\Migration\CalendarAdapter; -use OCP\ILogger; -use Test\TestCase; - -class MigrateCalendarTest extends TestCase { - - public function testMigration() { - /** @var CalendarAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ - $adapter = $this->mockAdapter([ - ['share_type' => '1', 'share_with' => 'users', 'permissions' => '31'], - ['share_type' => '2', 'share_with' => 'adam', 'permissions' => '1'], - ]); - - /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ - $cardDav = $this->getMockBuilder('\OCA\Dav\CalDAV\CalDAVBackend')->disableOriginalConstructor()->getMock(); - $cardDav->expects($this->any())->method('createCalendar')->willReturn(666); - $cardDav->expects($this->once())->method('createCalendar')->with('principals/users/test01', 'test_contacts'); - $cardDav->expects($this->once())->method('createCalendarObject')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', 'BEGIN:VCARD'); - $cardDav->expects($this->once())->method('updateShares')->with($this->anything(), [ - ['href' => 'principal:principals/groups/users', 'readOnly' => false], - ['href' => 'principal:principals/users/adam', 'readOnly' => true] - ]); - /** @var ILogger $logger */ - $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); - - $m = new \OCA\Dav\Migration\MigrateCalendars($adapter, $cardDav, $logger, null); - $m->migrateForUser('test01'); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function mockAdapter($shares = [], $calData = 'BEGIN:VCARD') { - $adapter = $this->getMockBuilder('\OCA\Dav\Migration\CalendarAdapter') - ->disableOriginalConstructor() - ->getMock(); - $adapter->expects($this->any())->method('foreachCalendar')->willReturnCallback(function ($user, \Closure $callBack) { - $callBack([ - // calendarorder | calendarcolor | timezone | components - 'id' => 0, - 'userid' => $user, - 'displayname' => 'Test Contacts', - 'uri' => 'test_contacts', - 'ctag' => 1234567890, - 'active' => 1, - 'calendarorder' => '0', - 'calendarcolor' => '#b3dc6c', - 'timezone' => null, - 'components' => 'VEVENT,VTODO,VJOURNAL' - ]); - }); - $adapter->expects($this->any())->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) use ($calData) { - $callBack([ - 'userid' => $addressBookId, - 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', - 'calendardata' => $calData - ]); - }); - $adapter->expects($this->any())->method('getShares')->willReturn($shares); - return $adapter; - } -} diff --git a/apps/dav/tests/unit/upload/assemblystreamtest.php b/apps/dav/tests/unit/upload/assemblystreamtest.php new file mode 100644 index 00000000000..373d525a9dd --- /dev/null +++ b/apps/dav/tests/unit/upload/assemblystreamtest.php @@ -0,0 +1,47 @@ +<?php + +class AssemblyStreamTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider providesNodes() + */ + public function testGetContents($expected, $nodes) { + $stream = \OCA\DAV\Upload\AssemblyStream::wrap($nodes); + $content = stream_get_contents($stream); + + $this->assertEquals($expected, $content); + } + + function providesNodes() { + return[ + 'one node only' => ['1234567890', [ + $this->buildNode('0', '1234567890') + ]], + 'two nodes' => ['1234567890', [ + $this->buildNode('1', '67890'), + $this->buildNode('0', '12345') + ]] + ]; + } + + private function buildNode($name, $data) { + $node = $this->getMockBuilder('\Sabre\DAV\File') + ->setMethods(['getName', 'get', 'getSize']) + ->getMockForAbstractClass(); + + $node->expects($this->any()) + ->method('getName') + ->willReturn($name); + + $node->expects($this->any()) + ->method('get') + ->willReturn($data); + + $node->expects($this->any()) + ->method('getSize') + ->willReturn(strlen($data)); + + return $node; + } +} + diff --git a/apps/dav/tests/unit/upload/futurefiletest.php b/apps/dav/tests/unit/upload/futurefiletest.php new file mode 100644 index 00000000000..c0c14bf04d7 --- /dev/null +++ b/apps/dav/tests/unit/upload/futurefiletest.php @@ -0,0 +1,89 @@ +<?php + +class FutureFileTest extends \PHPUnit_Framework_TestCase { + + public function testGetContentType() { + $f = $this->mockFutureFile(); + $this->assertEquals('application/octet-stream', $f->getContentType()); + } + + public function testGetETag() { + $f = $this->mockFutureFile(); + $this->assertEquals('1234567890', $f->getETag()); + } + + public function testGetName() { + $f = $this->mockFutureFile(); + $this->assertEquals('foo.txt', $f->getName()); + } + + public function testGetLastModified() { + $f = $this->mockFutureFile(); + $this->assertEquals(12121212, $f->getLastModified()); + } + + public function testGetSize() { + $f = $this->mockFutureFile(); + $this->assertEquals(0, $f->getSize()); + } + + public function testGet() { + $f = $this->mockFutureFile(); + $stream = $f->get(); + $this->assertTrue(is_resource($stream)); + } + + public function testDelete() { + $d = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Directory') + ->disableOriginalConstructor() + ->setMethods(['delete']) + ->getMock(); + + $d->expects($this->once()) + ->method('delete'); + + $f = new \OCA\DAV\Upload\FutureFile($d, 'foo.txt'); + $f->delete(); + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testPut() { + $f = $this->mockFutureFile(); + $f->put(''); + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testSetName() { + $f = $this->mockFutureFile(); + $f->setName(''); + } + + /** + * @return \OCA\DAV\Upload\FutureFile + */ + private function mockFutureFile() { + $d = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Directory') + ->disableOriginalConstructor() + ->setMethods(['getETag', 'getLastModified', 'getChildren']) + ->getMock(); + + $d->expects($this->any()) + ->method('getETag') + ->willReturn('1234567890'); + + $d->expects($this->any()) + ->method('getLastModified') + ->willReturn(12121212); + + $d->expects($this->any()) + ->method('getChildren') + ->willReturn([]); + + return new \OCA\DAV\Upload\FutureFile($d, 'foo.txt'); + } +} + diff --git a/apps/files/appinfo/application.php b/apps/files/appinfo/application.php index 593e0533c80..2d2decf6288 100644 --- a/apps/files/appinfo/application.php +++ b/apps/files/appinfo/application.php @@ -43,7 +43,8 @@ class Application extends App { $server->getUserSession(), $c->query('TagService'), $server->getPreviewManager(), - $server->getShareManager() + $server->getShareManager(), + $server->getConfig() ); }); diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php index 731c671b60a..6ad938101a2 100644 --- a/apps/files/appinfo/routes.php +++ b/apps/files/appinfo/routes.php @@ -1,6 +1,7 @@ <?php /** * @author Bart Visscher <bartv@thisnet.nl> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Roeland Jago Douma <rullzer@owncloud.com> * @author Tobias Kaminsky <tobias@kaminsky.me> @@ -48,6 +49,11 @@ $application->registerRoutes( 'verb' => 'GET', 'requirements' => array('tagName' => '.+'), ), + array( + 'name' => 'API#updateFileSorting', + 'url' => '/api/v1/sorting', + 'verb' => 'POST' + ), [ 'name' => 'view#index', 'url' => '/', diff --git a/apps/files/controller/apicontroller.php b/apps/files/controller/apicontroller.php index ad286284386..43d426476fe 100644 --- a/apps/files/controller/apicontroller.php +++ b/apps/files/controller/apicontroller.php @@ -1,6 +1,7 @@ <?php /** * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <rullzer@owncloud.com> @@ -29,13 +30,14 @@ namespace OCA\Files\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Controller; +use OCP\IConfig; use OCP\IRequest; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\Response; use OCA\Files\Service\TagService; use OCP\IPreview; use OCP\Share\IManager; -use OCP\Files\FileInfo; use OCP\Files\Node; use OCP\IUserSession; @@ -53,6 +55,8 @@ class ApiController extends Controller { private $previewManager; /** IUserSession */ private $userSession; + /** IConfig */ + private $config; /** * @param string $appName @@ -65,12 +69,14 @@ class ApiController extends Controller { IUserSession $userSession, TagService $tagService, IPreview $previewManager, - IManager $shareManager) { + IManager $shareManager, + IConfig $config) { parent::__construct($appName, $request); $this->userSession = $userSession; $this->tagService = $tagService; $this->previewManager = $previewManager; $this->shareManager = $shareManager; + $this->config = $config; } /** @@ -196,4 +202,26 @@ class ApiController extends Controller { return $shareTypes; } + /** + * Change the default sort mode + * + * @NoAdminRequired + * + * @param string $mode + * @param string $direction + * @return Response + */ + public function updateFileSorting($mode, $direction) { + $allowedMode = ['name', 'size', 'mtime']; + $allowedDirection = ['asc', 'desc']; + if (!in_array($mode, $allowedMode) || !in_array($direction, $allowedDirection)) { + $response = new Response(); + $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); + return $response; + } + $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'file_sorting', $mode); + $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'file_sorting_direction', $direction); + return new Response(); + } + } diff --git a/apps/files/controller/viewcontroller.php b/apps/files/controller/viewcontroller.php index 800cf008fa7..6c5f4c6d2a0 100644 --- a/apps/files/controller/viewcontroller.php +++ b/apps/files/controller/viewcontroller.php @@ -1,5 +1,6 @@ <?php /** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Thomas Müller <thomas.mueller@tmit.eu> * @@ -27,11 +28,12 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; use OCP\IL10N; use OCP\INavigationManager; use OCP\IRequest; use OCP\IURLGenerator; -use OCP\IConfig; +use OCP\IUserSession; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -54,6 +56,8 @@ class ViewController extends Controller { protected $config; /** @var EventDispatcherInterface */ protected $eventDispatcher; + /** @var IUserSession */ + protected $userSession; /** * @param string $appName @@ -70,7 +74,8 @@ class ViewController extends Controller { INavigationManager $navigationManager, IL10N $l10n, IConfig $config, - EventDispatcherInterface $eventDispatcherInterface) { + EventDispatcherInterface $eventDispatcherInterface, + IUserSession $userSession) { parent::__construct($appName, $request); $this->appName = $appName; $this->request = $request; @@ -79,6 +84,7 @@ class ViewController extends Controller { $this->l10n = $l10n; $this->config = $config; $this->eventDispatcher = $eventDispatcherInterface; + $this->userSession = $userSession; } /** @@ -213,6 +219,9 @@ class ViewController extends Controller { $params['mailNotificationEnabled'] = $this->config->getAppValue('core', 'shareapi_allow_mail_notification', 'no'); $params['mailPublicNotificationEnabled'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no'); $params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'); + $user = $this->userSession->getUser()->getUID(); + $params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name'); + $params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc'); $params['appNavigation'] = $nav; $params['appContents'] = $contentItems; $this->navigationManager->setActiveEntry('files_index'); diff --git a/apps/files/js/app.js b/apps/files/js/app.js index ff505d417f1..4ed805d2681 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -72,7 +72,11 @@ fileActions: fileActions, allowLegacyActions: true, scrollTo: urlParams.scrollto, - filesClient: OC.Files.getClient() + filesClient: OC.Files.getClient(), + sorting: { + mode: $('#defaultFileSorting').val(), + direction: $('#defaultFileSortingDirection').val() + } } ); this.files.initialize(); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index c8f818701a9..7de64f8ade3 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -239,7 +239,11 @@ this.fileSummary = this._createSummary(); - this.setSort('name', 'asc'); + if (options.sorting) { + this.setSort(options.sorting.mode, options.sorting.direction, false, false); + } else { + this.setSort('name', 'asc', false, false); + } var breadcrumbOptions = { onClick: _.bind(this._onClickBreadCrumb, this), @@ -695,14 +699,14 @@ sort = $target.attr('data-sort'); if (sort) { if (this._sort === sort) { - this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true); + this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true, true); } else { if ( sort === 'name' ) { //default sorting of name is opposite to size and mtime - this.setSort(sort, 'asc', true); + this.setSort(sort, 'asc', true, true); } else { - this.setSort(sort, 'desc', true); + this.setSort(sort, 'desc', true, true); } } } @@ -1370,8 +1374,9 @@ * @param sort sort attribute name * @param direction sort direction, one of "asc" or "desc" * @param update true to update the list, false otherwise (default) + * @param persist true to save changes in the database (default) */ - setSort: function(sort, direction, update) { + setSort: function(sort, direction, update, persist) { var comparator = FileList.Comparators[sort] || FileList.Comparators.name; this._sort = sort; this._sortDirection = (direction === 'desc')?'desc':'asc'; @@ -1402,6 +1407,13 @@ this.reload(); } } + + if (persist) { + $.post(OC.generateUrl('/apps/files/api/v1/sorting'), { + mode: sort, + direction: direction + }); + } }, /** diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index e825c300d31..db464ad2eca 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -18,4 +18,6 @@ <input type="hidden" name="mailNotificationEnabled" id="mailNotificationEnabled" value="<?php p($_['mailNotificationEnabled']) ?>" /> <input type="hidden" name="mailPublicNotificationEnabled" id="mailPublicNotificationEnabled" value="<?php p($_['mailPublicNotificationEnabled']) ?>" /> <input type="hidden" name="allowShareWithLink" id="allowShareWithLink" value="<?php p($_['allowShareWithLink']) ?>" /> +<input type="hidden" name="defaultFileSorting" id="defaultFileSorting" value="<?php p($_['defaultFileSorting']) ?>" /> +<input type="hidden" name="defaultFileSortingDirection" id="defaultFileSortingDirection" value="<?php p($_['defaultFileSortingDirection']) ?>" /> <?php endif; diff --git a/apps/files/tests/controller/ViewControllerTest.php b/apps/files/tests/controller/ViewControllerTest.php index 657ab6cb338..0446cc8982c 100644 --- a/apps/files/tests/controller/ViewControllerTest.php +++ b/apps/files/tests/controller/ViewControllerTest.php @@ -1,5 +1,6 @@ <?php /** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <nickvergessen@owncloud.com> * @author Lukas Reschke <lukas@owncloud.com> * @author Vincent Petry <pvince81@owncloud.com> @@ -33,6 +34,7 @@ use OCP\AppFramework\Http\RedirectResponse; use OCP\INavigationManager; use OCP\IL10N; use OCP\IConfig; +use OCP\IUserSession; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -55,6 +57,10 @@ class ViewControllerTest extends TestCase { private $eventDispatcher; /** @var ViewController */ private $viewController; + /** @var IUser */ + private $user; + /** @var IUserSession */ + private $userSession; public function setUp() { parent::setUp(); @@ -64,6 +70,11 @@ class ViewControllerTest extends TestCase { $this->l10n = $this->getMock('\OCP\IL10N'); $this->config = $this->getMock('\OCP\IConfig'); $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->userSession = $this->getMock('\OCP\IUserSession'); + $this->user = $this->getMock('\OCP\IUser'); + $this->userSession->expects($this->any()) + ->method('getUser') + ->will($this->returnValue($this->user)); $this->viewController = $this->getMockBuilder('\OCA\Files\Controller\ViewController') ->setConstructorArgs([ 'files', @@ -72,7 +83,8 @@ class ViewControllerTest extends TestCase { $this->navigationManager, $this->l10n, $this->config, - $this->eventDispatcher + $this->eventDispatcher, + $this->userSession ]) ->setMethods([ 'getStorageInfo', @@ -143,6 +155,12 @@ class ViewControllerTest extends TestCase { 'owner' => 'MyName', 'ownerDisplayName' => 'MyDisplayName', ])); + $this->config->expects($this->exactly(2)) + ->method('getUserValue') + ->will($this->returnValueMap([ + [$this->user->getUID(), 'files', 'file_sorting', 'name', 'name'], + [$this->user->getUID(), 'files', 'file_sorting_direction', 'asc', 'asc'] + ])); $this->config ->expects($this->any()) @@ -224,6 +242,8 @@ class ViewControllerTest extends TestCase { 'owner' => 'MyName', 'ownerDisplayName' => 'MyDisplayName', 'isPublic' => false, + 'defaultFileSorting' => 'name', + 'defaultFileSortingDirection' => 'asc', 'mailNotificationEnabled' => 'no', 'mailPublicNotificationEnabled' => 'no', 'allowShareWithLink' => 'yes', diff --git a/apps/files/tests/controller/apicontrollertest.php b/apps/files/tests/controller/apicontrollertest.php index a9b248a36fe..59f53e8ee81 100644 --- a/apps/files/tests/controller/apicontrollertest.php +++ b/apps/files/tests/controller/apicontrollertest.php @@ -1,5 +1,6 @@ <?php /** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <rullzer@owncloud.com> @@ -43,6 +44,8 @@ use OCP\Image; class ApiControllerTest extends TestCase { /** @var string */ private $appName = 'files'; + /** @var \OCP\IUser */ + private $user; /** @var IRequest */ private $request; /** @var TagService */ @@ -53,19 +56,21 @@ class ApiControllerTest extends TestCase { private $apiController; /** @var \OCP\Share\IManager */ private $shareManager; + /** @var \OCP\IConfig */ + private $config; public function setUp() { $this->request = $this->getMockBuilder('\OCP\IRequest') ->disableOriginalConstructor() ->getMock(); - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->any()) + $this->user = $this->getMock('\OCP\IUser'); + $this->user->expects($this->any()) ->method('getUID') ->will($this->returnValue('user1')); $userSession = $this->getMock('\OCP\IUserSession'); $userSession->expects($this->any()) ->method('getUser') - ->will($this->returnValue($user)); + ->will($this->returnValue($this->user)); $this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService') ->disableOriginalConstructor() ->getMock(); @@ -75,6 +80,7 @@ class ApiControllerTest extends TestCase { $this->preview = $this->getMockBuilder('\OCP\IPreview') ->disableOriginalConstructor() ->getMock(); + $this->config = $this->getMock('\OCP\IConfig'); $this->apiController = new ApiController( $this->appName, @@ -82,7 +88,8 @@ class ApiControllerTest extends TestCase { $userSession, $this->tagService, $this->preview, - $this->shareManager + $this->shareManager, + $this->config ); } @@ -335,4 +342,44 @@ class ApiControllerTest extends TestCase { $this->assertEquals(Http::STATUS_OK, $ret->getStatus()); } + + public function testUpdateFileSorting() { + $mode = 'mtime'; + $direction = 'desc'; + + $this->config->expects($this->at(0)) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'file_sorting', $mode); + $this->config->expects($this->at(1)) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'file_sorting_direction', $direction); + + $expected = new HTTP\Response(); + $actual = $this->apiController->updateFileSorting($mode, $direction); + $this->assertEquals($expected, $actual); + } + + public function invalidSortingModeData() { + return [ + ['color', 'asc'], + ['name', 'size'], + ['foo', 'bar'] + ]; + } + + /** + * @dataProvider invalidSortingModeData + */ + public function testUpdateInvalidFileSorting($mode, $direction) { + $this->config->expects($this->never()) + ->method('setUserValue'); + + $expected = new Http\Response(null); + $expected->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); + + $result = $this->apiController->updateFileSorting($mode, $direction); + + $this->assertEquals($expected, $result); + } + } diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index a83c8c4c0bc..cc3bcd74b46 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -2106,6 +2106,8 @@ describe('OCA.Files.FileList tests', function() { it('Toggles the sort indicator when clicking on a column header', function() { var ASC_CLASS = fileList.SORT_INDICATOR_ASC_CLASS; var DESC_CLASS = fileList.SORT_INDICATOR_DESC_CLASS; + var request; + var sortingUrl = OC.generateUrl('/apps/files/api/v1/sorting'); fileList.$el.find('.column-size .columntitle').click(); // moves triangle to size column, check indicator on name is hidden expect( @@ -2118,6 +2120,10 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) ).toEqual(true); + // check if changes are persisted + expect(fakeServer.requests.length).toEqual(1); + request = fakeServer.requests[0]; + expect(request.url).toEqual(sortingUrl); // click again on size column, reverses direction fileList.$el.find('.column-size .columntitle').click(); @@ -2127,6 +2133,10 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS) ).toEqual(true); + // check if changes are persisted + expect(fakeServer.requests.length).toEqual(2); + request = fakeServer.requests[1]; + expect(request.url).toEqual(sortingUrl); // click again on size column, reverses direction fileList.$el.find('.column-size .columntitle').click(); @@ -2136,6 +2146,9 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) ).toEqual(true); + expect(fakeServer.requests.length).toEqual(3); + request = fakeServer.requests[2]; + expect(request.url).toEqual(sortingUrl); // click on mtime column, moves indicator there fileList.$el.find('.column-mtime .columntitle').click(); @@ -2148,6 +2161,9 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-mtime .sort-indicator').hasClass(DESC_CLASS) ).toEqual(true); + expect(fakeServer.requests.length).toEqual(4); + request = fakeServer.requests[3]; + expect(request.url).toEqual(sortingUrl); }); it('Uses correct sort comparator when inserting files', function() { testFiles.sort(OCA.Files.FileList.Comparators.size); diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 46a4ecf0793..18f8b2551fa 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -26,17 +26,7 @@ * */ -OC::$CLASSPATH['OC\Files\Storage\StreamWrapper'] = 'files_external/lib/streamwrapper.php'; -OC::$CLASSPATH['OC\Files\Storage\FTP'] = 'files_external/lib/ftp.php'; -OC::$CLASSPATH['OC\Files\Storage\OwnCloud'] = 'files_external/lib/owncloud.php'; -OC::$CLASSPATH['OC\Files\Storage\Google'] = 'files_external/lib/google.php'; -OC::$CLASSPATH['OC\Files\Storage\Swift'] = 'files_external/lib/swift.php'; -OC::$CLASSPATH['OC\Files\Storage\SMB'] = 'files_external/lib/smb.php'; -OC::$CLASSPATH['OC\Files\Storage\AmazonS3'] = 'files_external/lib/amazons3.php'; -OC::$CLASSPATH['OC\Files\Storage\Dropbox'] = 'files_external/lib/dropbox.php'; -OC::$CLASSPATH['OC\Files\Storage\SFTP'] = 'files_external/lib/sftp.php'; OC::$CLASSPATH['OC_Mount_Config'] = 'files_external/lib/config.php'; -OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php'; require_once __DIR__ . '/../3rdparty/autoload.php'; diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php index 2d2e6ddf607..e2f55e652a8 100644 --- a/apps/files_external/appinfo/routes.php +++ b/apps/files_external/appinfo/routes.php @@ -61,6 +61,6 @@ $this->create('files_external_list_applicable', '/applicable') \OCP\API::register('get', '/apps/files_external/api/v1/mounts', - array('\OCA\Files\External\Api', 'getUserMounts'), + array('\OCA\Files_External\Lib\Api', 'getUserMounts'), 'files_external'); diff --git a/apps/files_external/lib/api.php b/apps/files_external/lib/api.php index 50a2f38c65b..589317dcf98 100644 --- a/apps/files_external/lib/api.php +++ b/apps/files_external/lib/api.php @@ -23,7 +23,7 @@ * */ -namespace OCA\Files\External; +namespace OCA\Files_External\Lib; class Api { diff --git a/apps/files_external/lib/backend/amazons3.php b/apps/files_external/lib/backend/amazons3.php index b2dedc10e4a..449b6c0379d 100644 --- a/apps/files_external/lib/backend/amazons3.php +++ b/apps/files_external/lib/backend/amazons3.php @@ -38,7 +38,7 @@ class AmazonS3 extends Backend { $this ->setIdentifier('amazons3') ->addIdentifierAlias('\OC\Files\Storage\AmazonS3') // legacy compat - ->setStorageClass('\OC\Files\Storage\AmazonS3') + ->setStorageClass('\OCA\Files_External\Lib\Storage\AmazonS3') ->setText($l->t('Amazon S3')) ->addParameters([ (new DefinitionParameter('bucket', $l->t('Bucket'))), diff --git a/apps/files_external/lib/backend/dropbox.php b/apps/files_external/lib/backend/dropbox.php index 7a414731192..f9156082515 100644 --- a/apps/files_external/lib/backend/dropbox.php +++ b/apps/files_external/lib/backend/dropbox.php @@ -38,7 +38,7 @@ class Dropbox extends Backend { $this ->setIdentifier('dropbox') ->addIdentifierAlias('\OC\Files\Storage\Dropbox') // legacy compat - ->setStorageClass('\OC\Files\Storage\Dropbox') + ->setStorageClass('\OCA\Files_External\Lib\Storage\Dropbox') ->setText($l->t('Dropbox')) ->addParameters([ // all parameters handled in OAuth1 mechanism diff --git a/apps/files_external/lib/backend/ftp.php b/apps/files_external/lib/backend/ftp.php index b2b83a27405..3960592d0bc 100644 --- a/apps/files_external/lib/backend/ftp.php +++ b/apps/files_external/lib/backend/ftp.php @@ -38,7 +38,7 @@ class FTP extends Backend { $this ->setIdentifier('ftp') ->addIdentifierAlias('\OC\Files\Storage\FTP') // legacy compat - ->setStorageClass('\OC\Files\Storage\FTP') + ->setStorageClass('\OCA\Files_External\Lib\Storage\FTP') ->setText($l->t('FTP')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/google.php b/apps/files_external/lib/backend/google.php index 93a8cd2177d..b2b48a0e402 100644 --- a/apps/files_external/lib/backend/google.php +++ b/apps/files_external/lib/backend/google.php @@ -38,7 +38,7 @@ class Google extends Backend { $this ->setIdentifier('googledrive') ->addIdentifierAlias('\OC\Files\Storage\Google') // legacy compat - ->setStorageClass('\OC\Files\Storage\Google') + ->setStorageClass('\OCA\Files_External\Lib\Storage\Google') ->setText($l->t('Google Drive')) ->addParameters([ // all parameters handled in OAuth2 mechanism diff --git a/apps/files_external/lib/backend/owncloud.php b/apps/files_external/lib/backend/owncloud.php index e7da328c5f1..e92288b1354 100644 --- a/apps/files_external/lib/backend/owncloud.php +++ b/apps/files_external/lib/backend/owncloud.php @@ -35,7 +35,7 @@ class OwnCloud extends Backend { $this ->setIdentifier('owncloud') ->addIdentifierAlias('\OC\Files\Storage\OwnCloud') // legacy compat - ->setStorageClass('\OC\Files\Storage\OwnCloud') + ->setStorageClass('\OCA\Files_External\Lib\Storage\OwnCloud') ->setText($l->t('ownCloud')) ->addParameters([ (new DefinitionParameter('host', $l->t('URL'))), diff --git a/apps/files_external/lib/backend/sftp.php b/apps/files_external/lib/backend/sftp.php index 3e5ecb90131..fa33caeb576 100644 --- a/apps/files_external/lib/backend/sftp.php +++ b/apps/files_external/lib/backend/sftp.php @@ -35,7 +35,7 @@ class SFTP extends Backend { $this ->setIdentifier('sftp') ->addIdentifierAlias('\OC\Files\Storage\SFTP') // legacy compat - ->setStorageClass('\OC\Files\Storage\SFTP') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SFTP') ->setText($l->t('SFTP')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/sftp_key.php b/apps/files_external/lib/backend/sftp_key.php index 58dddedf784..838cf6c52b2 100644 --- a/apps/files_external/lib/backend/sftp_key.php +++ b/apps/files_external/lib/backend/sftp_key.php @@ -34,7 +34,7 @@ class SFTP_Key extends Backend { public function __construct(IL10N $l, RSA $legacyAuth, SFTP $sftpBackend) { $this ->setIdentifier('\OC\Files\Storage\SFTP_Key') - ->setStorageClass('\OC\Files\Storage\SFTP') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SFTP') ->setText($l->t('SFTP with secret key login')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/smb.php b/apps/files_external/lib/backend/smb.php index 9b71636936a..7ea30dd11bd 100644 --- a/apps/files_external/lib/backend/smb.php +++ b/apps/files_external/lib/backend/smb.php @@ -40,7 +40,7 @@ class SMB extends Backend { $this ->setIdentifier('smb') ->addIdentifierAlias('\OC\Files\Storage\SMB') // legacy compat - ->setStorageClass('\OC\Files\Storage\SMB') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB') ->setText($l->t('SMB / CIFS')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/smb_oc.php b/apps/files_external/lib/backend/smb_oc.php index ba38754ce5a..c543a19bdd8 100644 --- a/apps/files_external/lib/backend/smb_oc.php +++ b/apps/files_external/lib/backend/smb_oc.php @@ -42,7 +42,7 @@ class SMB_OC extends Backend { public function __construct(IL10N $l, SessionCredentials $legacyAuth, SMB $smbBackend) { $this ->setIdentifier('\OC\Files\Storage\SMB_OC') - ->setStorageClass('\OC\Files\Storage\SMB') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB') ->setText($l->t('SMB / CIFS using OC login')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/swift.php b/apps/files_external/lib/backend/swift.php index d6e4ac12f9a..58677575f52 100644 --- a/apps/files_external/lib/backend/swift.php +++ b/apps/files_external/lib/backend/swift.php @@ -38,7 +38,7 @@ class Swift extends Backend { $this ->setIdentifier('swift') ->addIdentifierAlias('\OC\Files\Storage\Swift') // legacy compat - ->setStorageClass('\OC\Files\Storage\Swift') + ->setStorageClass('\OCA\Files_External\Lib\Storage\Swift') ->setText($l->t('OpenStack Object Storage')) ->addParameters([ (new DefinitionParameter('service_name', $l->t('Service name'))) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/storage/amazons3.php index cb2082ee38b..42df1deffb0 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/storage/amazons3.php @@ -33,7 +33,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; set_include_path(get_include_path() . PATH_SEPARATOR . \OC_App::getAppPath('files_external') . '/3rdparty/aws-sdk-php'); diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/storage/dropbox.php index 8381ccbae59..55ae7146572 100644 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/storage/dropbox.php @@ -27,13 +27,13 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use GuzzleHttp\Exception\RequestException; use Icewind\Streams\IteratorDirectory; use Icewind\Streams\RetryWrapper; -require_once __DIR__ . '/../3rdparty/Dropbox/autoload.php'; +require_once __DIR__ . '/../../3rdparty/Dropbox/autoload.php'; class Dropbox extends \OC\Files\Storage\Common { @@ -59,7 +59,7 @@ class Dropbox extends \OC\Files\Storage\Common { // note: Dropbox_API connection is lazy $this->dropbox = new \Dropbox_API($this->oauth, 'auto'); } else { - throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed'); + throw new \Exception('Creating Dropbox storage failed'); } } diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/storage/ftp.php index 7249aeceb5d..051c1873009 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/storage/ftp.php @@ -28,11 +28,11 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Icewind\Streams\RetryWrapper; -class FTP extends \OC\Files\Storage\StreamWrapper{ +class FTP extends StreamWrapper{ private $password; private $user; private $host; @@ -59,7 +59,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $this->root .= '/'; } } else { - throw new \Exception('Creating \OC\Files\Storage\FTP storage failed'); + throw new \Exception('Creating FTP storage failed'); } } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/storage/google.php index 62d264dfeef..8d1fe808130 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/storage/google.php @@ -31,7 +31,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use GuzzleHttp\Exception\RequestException; use Icewind\Streams\IteratorDirectory; @@ -79,7 +79,7 @@ class Google extends \OC\Files\Storage\Common { $token = json_decode($params['token'], true); $this->id = 'google::'.substr($params['client_id'], 0, 30).$token['created']; } else { - throw new \Exception('Creating \OC\Files\Storage\Google storage failed'); + throw new \Exception('Creating Google storage failed'); } } diff --git a/apps/files_external/lib/owncloud.php b/apps/files_external/lib/storage/owncloud.php index c4824e6bd14..22ecb4c806a 100644 --- a/apps/files_external/lib/owncloud.php +++ b/apps/files_external/lib/storage/owncloud.php @@ -21,7 +21,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; /** * ownCloud backend for external storage based on DAV backend. diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/storage/sftp.php index a6984f3b4e0..2375f84dcda 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/storage/sftp.php @@ -29,7 +29,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Icewind\Streams\IteratorDirectory; use Icewind\Streams\RetryWrapper; diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/storage/smb.php index 08c4b25a088..4249d13168c 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/storage/smb.php @@ -28,7 +28,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Icewind\SMB\Exception\ConnectException; use Icewind\SMB\Exception\Exception; @@ -42,7 +42,7 @@ use OC\Cache\CappedMemoryCache; use OC\Files\Filesystem; use OCP\Files\StorageNotAvailableException; -class SMB extends Common { +class SMB extends \OC\Files\Storage\Common { /** * @var \Icewind\SMB\Server */ diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/storage/streamwrapper.php index efb51f32ba4..0b4dff78c4f 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/storage/streamwrapper.php @@ -24,9 +24,9 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; -abstract class StreamWrapper extends Common { +abstract class StreamWrapper extends \OC\Files\Storage\Common { /** * @param string $path diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/storage/swift.php index 9282fe28669..4578cd9a5c7 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/storage/swift.php @@ -32,7 +32,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Guzzle\Http\Url; use Guzzle\Http\Exception\ClientErrorResponseException; diff --git a/apps/files_external/tests/amazons3migration.php b/apps/files_external/tests/amazons3migration.php index d4ea9e2c261..614d6ca33df 100644 --- a/apps/files_external/tests/amazons3migration.php +++ b/apps/files_external/tests/amazons3migration.php @@ -24,14 +24,16 @@ */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests; + +use OCA\Files_External\Lib\Storage\AmazonS3; /** * Class AmazonS3Migration * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests */ class AmazonS3Migration extends \Test\TestCase { @@ -77,7 +79,7 @@ class AmazonS3Migration extends \Test\TestCase { $fileId = $oldCache->put('foobar', array('size' => 0, 'mtime' => time(), 'mimetype' => 'httpd/directory')); try { - $this->instance = new \OC\Files\Storage\AmazonS3($this->params); + $this->instance = new AmazonS3($this->params); } catch (\Exception $e) { //ignore } @@ -103,7 +105,7 @@ class AmazonS3Migration extends \Test\TestCase { $fileId = $oldCache->put('/', array('size' => 0, 'mtime' => time(), 'mimetype' => 'httpd/directory')); try { - $this->instance = new \OC\Files\Storage\AmazonS3($this->params); + $this->instance = new AmazonS3($this->params); } catch (\Exception $e) { //ignore } diff --git a/apps/files_external/tests/controller/storagescontrollertest.php b/apps/files_external/tests/controller/storagescontrollertest.php index 5854cb00fee..4c3c62d5d6f 100644 --- a/apps/files_external/tests/controller/storagescontrollertest.php +++ b/apps/files_external/tests/controller/storagescontrollertest.php @@ -51,7 +51,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { /** * @return \OCA\Files_External\Lib\Backend\Backend */ - protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') { + protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OCA\Files_External\Lib\Storage\SMB') { $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend') ->disableOriginalConstructor() ->getMock(); @@ -104,7 +104,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->create( 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -146,7 +146,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->update( 1, 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -188,7 +188,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->create( $mountPoint, - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -202,7 +202,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->update( 1, $mountPoint, - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -279,7 +279,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->update( 255, 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -375,7 +375,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->create( 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], diff --git a/apps/files_external/tests/controller/userstoragescontrollertest.php b/apps/files_external/tests/controller/userstoragescontrollertest.php index a7e854471b5..804b752b6af 100644 --- a/apps/files_external/tests/controller/userstoragescontrollertest.php +++ b/apps/files_external/tests/controller/userstoragescontrollertest.php @@ -78,7 +78,7 @@ class UserStoragesControllerTest extends StoragesControllerTest { $response = $this->controller->create( 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\Auth\Mechanism', array(), [], @@ -92,7 +92,7 @@ class UserStoragesControllerTest extends StoragesControllerTest { $response = $this->controller->update( 1, 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\Auth\Mechanism', array(), [], diff --git a/apps/files_external/tests/owncloudfunctions.php b/apps/files_external/tests/owncloudfunctions.php index 019f988275e..25aaa90d178 100644 --- a/apps/files_external/tests/owncloudfunctions.php +++ b/apps/files_external/tests/owncloudfunctions.php @@ -23,14 +23,14 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests; /** * Class OwnCloudFunctions * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests */ class OwnCloudFunctions extends \Test\TestCase { @@ -109,7 +109,7 @@ class OwnCloudFunctions extends \Test\TestCase { public function testConfig($config, $expectedUri) { $config['user'] = 'someuser'; $config['password'] = 'somepassword'; - $instance = new \OC\Files\Storage\OwnCloud($config); + $instance = new \OCA\Files_External\Lib\Storage\OwnCloud($config); $this->assertEquals($expectedUri, $instance->createBaseUri()); } } diff --git a/apps/files_external/tests/service/storagesservicetest.php b/apps/files_external/tests/service/storagesservicetest.php index 3fbe3b755e1..f93c0134814 100644 --- a/apps/files_external/tests/service/storagesservicetest.php +++ b/apps/files_external/tests/service/storagesservicetest.php @@ -121,9 +121,9 @@ abstract class StoragesServiceTest extends \Test\TestCase { $this->backendService->method('getAuthMechanisms') ->will($this->returnValue($authMechanisms)); - $sftpBackend = $this->getBackendMock('\OCA\Files_External\Lib\Backend\SFTP', '\OC\Files\Storage\SFTP'); + $sftpBackend = $this->getBackendMock('\OCA\Files_External\Lib\Backend\SFTP', '\OCA\Files_External\Lib\Storage\SFTP'); $backends = [ - 'identifier:\OCA\Files_External\Lib\Backend\SMB' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SMB', '\OC\Files\Storage\SMB'), + 'identifier:\OCA\Files_External\Lib\Backend\SMB' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SMB', '\OCA\Files_External\Lib\Storage\SMB'), 'identifier:\OCA\Files_External\Lib\Backend\SFTP' => $sftpBackend, 'identifier:sftp_alias' => $sftpBackend, ]; @@ -171,7 +171,7 @@ abstract class StoragesServiceTest extends \Test\TestCase { } } - protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') { + protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OCA\Files_External\Lib\Storage\SMB') { $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend') ->disableOriginalConstructor() ->getMock(); diff --git a/apps/files_external/tests/backends/amazons3.php b/apps/files_external/tests/storage/amazons3test.php index 3b43f81a926..eb0e410764c 100644 --- a/apps/files_external/tests/backends/amazons3.php +++ b/apps/files_external/tests/storage/amazons3test.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\AmazonS3; /** - * Class AmazonS3 + * Class AmazonS3Test * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class AmazonS3 extends Storage { +class AmazonS3Test extends \Test\Files\Storage\Storage { private $config; @@ -44,7 +46,7 @@ class AmazonS3 extends Storage { if ( ! is_array($this->config) or ! $this->config['run']) { $this->markTestSkipped('AmazonS3 backend not configured'); } - $this->instance = new \OC\Files\Storage\AmazonS3($this->config); + $this->instance = new AmazonS3($this->config); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/dropbox.php b/apps/files_external/tests/storage/dropboxtest.php index 1bf8b4171fb..d466d4b1b44 100644 --- a/apps/files_external/tests/backends/dropbox.php +++ b/apps/files_external/tests/storage/dropboxtest.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\Dropbox; /** - * Class Dropbox + * Class DropboxTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class Dropbox extends Storage { +class DropboxTest extends \Test\Files\Storage\Storage { private $config; protected function setUp() { @@ -45,7 +47,7 @@ class Dropbox extends Storage { $this->markTestSkipped('Dropbox backend not configured'); } $this->config['dropbox']['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\Dropbox($this->config['dropbox']); + $this->instance = new Dropbox($this->config['dropbox']); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/ftp.php b/apps/files_external/tests/storage/ftptest.php index 868a022d38f..9af9ccff012 100644 --- a/apps/files_external/tests/backends/ftp.php +++ b/apps/files_external/tests/storage/ftptest.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\FTP; /** - * Class FTP + * Class FTPTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class FTP extends Storage { +class FTPTest extends \Test\Files\Storage\Storage { private $config; protected function setUp() { @@ -45,7 +47,7 @@ class FTP extends Storage { $this->markTestSkipped('FTP backend not configured'); } $this->config['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\FTP($this->config); + $this->instance = new FTP($this->config); $this->instance->mkdir('/'); } @@ -63,31 +65,31 @@ class FTP extends Storage { 'password' => 'ftp', 'root' => '/', 'secure' => false ); - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = true; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'false'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'true'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); $config['root'] = ''; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/somefile.txt', $instance->constructUrl('somefile.txt')); $config['root'] = '/abc'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/abc/somefile.txt', $instance->constructUrl('somefile.txt')); $config['root'] = '/abc/'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/abc/somefile.txt', $instance->constructUrl('somefile.txt')); } } diff --git a/apps/files_external/tests/backends/google.php b/apps/files_external/tests/storage/googletest.php index 7622f796407..46aa4555b12 100644 --- a/apps/files_external/tests/backends/google.php +++ b/apps/files_external/tests/storage/googletest.php @@ -25,18 +25,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; -require_once 'files_external/lib/google.php'; +use \OCA\Files_External\Lib\Storage\Google; /** - * Class Google + * Class GoogleTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class Google extends Storage { +class GoogleTest extends \Test\Files\Storage\Storage { private $config; @@ -49,7 +49,7 @@ class Google extends Storage { ) { $this->markTestSkipped('Google Drive backend not configured'); } - $this->instance = new \OC\Files\Storage\Google($this->config['google']); + $this->instance = new Google($this->config['google']); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/owncloud.php b/apps/files_external/tests/storage/owncloudtest.php index a56e9b2a186..cbc25e46fa0 100644 --- a/apps/files_external/tests/backends/owncloud.php +++ b/apps/files_external/tests/storage/owncloudtest.php @@ -22,16 +22,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\OwnCloud; /** - * Class OwnCloud + * Class OwnCloudTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class OwnCloud extends Storage { +class OwnCloudTest extends \Test\Files\Storage\Storage { private $config; @@ -44,7 +46,7 @@ class OwnCloud extends Storage { $this->markTestSkipped('ownCloud backend not configured'); } $this->config['owncloud']['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\OwnCloud($this->config['owncloud']); + $this->instance = new OwnCloud($this->config['owncloud']); $this->instance->mkdir('/'); } diff --git a/apps/files_external/tests/backends/sftp_key.php b/apps/files_external/tests/storage/sftp_keytest.php index 73c6a0b6432..b974f88555f 100644 --- a/apps/files_external/tests/backends/sftp_key.php +++ b/apps/files_external/tests/storage/sftp_keytest.php @@ -22,16 +22,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\SFTP_Key; /** - * Class SFTP_Key + * Class SFTP_KeyTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class SFTP_Key extends Storage { +class SFTP_KeyTest extends \Test\Files\Storage\Storage { private $config; protected function setUp() { @@ -44,7 +46,7 @@ class SFTP_Key extends Storage { } // Make sure we have an new empty folder to work in $this->config['sftp_key']['root'] .= '/' . $id; - $this->instance = new \OC\Files\Storage\SFTP_Key($this->config['sftp_key']); + $this->instance = new SFTP_Key($this->config['sftp_key']); $this->instance->mkdir('/'); } diff --git a/apps/files_external/tests/backends/sftp.php b/apps/files_external/tests/storage/sftptest.php index 608982adbc4..329e93819fc 100644 --- a/apps/files_external/tests/backends/sftp.php +++ b/apps/files_external/tests/storage/sftptest.php @@ -24,18 +24,20 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\SFTP; /** - * Class SFTP + * Class SFTPTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class SFTP extends Storage { +class SFTPTest extends \Test\Files\Storage\Storage { /** - * @var \OC\Files\Storage\SFTP instance + * @var SFTP instance */ protected $instance; @@ -50,7 +52,7 @@ class SFTP extends Storage { $this->markTestSkipped('SFTP backend not configured'); } $this->config['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\SFTP($this->config); + $this->instance = new SFTP($this->config); $this->instance->mkdir('/'); } @@ -66,7 +68,7 @@ class SFTP extends Storage { * @dataProvider configProvider */ public function testStorageId($config, $expectedStorageId) { - $instance = new \OC\Files\Storage\SFTP($config); + $instance = new SFTP($config); $this->assertEquals($expectedStorageId, $instance->getId()); } diff --git a/apps/files_external/tests/backends/smb.php b/apps/files_external/tests/storage/smbtest.php index f9a377c271b..fc2795702c6 100644 --- a/apps/files_external/tests/backends/smb.php +++ b/apps/files_external/tests/storage/smbtest.php @@ -23,16 +23,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\SMB; /** - * Class SMB + * Class SMBTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class SMB extends Storage { +class SMBTest extends \Test\Files\Storage\Storage { protected function setUp() { parent::setUp(); @@ -46,7 +48,7 @@ class SMB extends Storage { $config['root'] .= '/'; } $config['root'] .= $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\SMB($config); + $this->instance = new SMB($config); $this->instance->mkdir('/'); } @@ -71,7 +73,7 @@ class SMB extends Storage { } public function testStorageId() { - $this->instance = new \OC\Files\Storage\SMB([ + $this->instance = new SMB([ 'host' => 'testhost', 'user' => 'testuser', 'password' => 'somepass', diff --git a/apps/files_external/tests/backends/swift.php b/apps/files_external/tests/storage/swifttest.php index 9bdcd48ee68..1bcbb815067 100644 --- a/apps/files_external/tests/backends/swift.php +++ b/apps/files_external/tests/storage/swifttest.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\Swift; /** - * Class Swift + * Class SwiftTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class Swift extends Storage { +class SwiftTest extends \Test\Files\Storage\Storage { private $config; @@ -44,7 +46,7 @@ class Swift extends Storage { if (!is_array($this->config) or !$this->config['run']) { $this->markTestSkipped('OpenStack Object Storage backend not configured'); } - $this->instance = new \OC\Files\Storage\Swift($this->config); + $this->instance = new Swift($this->config); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/webdav.php b/apps/files_external/tests/storage/webdavtest.php index e1a710c94b4..f8c5b19e04f 100644 --- a/apps/files_external/tests/backends/webdav.php +++ b/apps/files_external/tests/storage/webdavtest.php @@ -23,16 +23,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OC\Files\Storage\DAV; /** - * Class DAV + * Class WebDAVTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class DAV extends Storage { +class WebDAVTest extends \Test\Files\Storage\Storage { protected function setUp() { parent::setUp(); @@ -46,7 +48,7 @@ class DAV extends Storage { $this->waitDelay = $config['wait']; } $config['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\DAV($config); + $this->instance = new DAV($config); $this->instance->mkdir('/'); } diff --git a/apps/files_sharing/lib/mountprovider.php b/apps/files_sharing/lib/mountprovider.php index 4a60e44bb26..6c8bbb62ee7 100644 --- a/apps/files_sharing/lib/mountprovider.php +++ b/apps/files_sharing/lib/mountprovider.php @@ -55,19 +55,20 @@ class MountProvider implements IMountProvider { $shares = array_filter($shares, function ($share) { return $share['permissions'] > 0; }); - $shares = array_map(function ($share) use ($user, $storageFactory) { - - return new SharedMount( + $mounts = []; + foreach ($shares as $share) { + $mounts[] = new SharedMount( '\OC\Files\Storage\Shared', - '/' . $user->getUID() . '/' . $share['file_target'], - array( + $mounts, + [ 'share' => $share, 'user' => $user->getUID() - ), + ], $storageFactory ); - }, $shares); + } + // array_filter removes the null values from the array - return array_filter($shares); + return array_filter($mounts); } } diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 1e554cc5948..311e81269db 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -25,6 +25,7 @@ namespace OCA\Files_Sharing; +use OC\Files\Filesystem; use OC\Files\Mount\MountPoint; use OC\Files\Mount\MoveableMount; use OC\Files\View; @@ -50,14 +51,14 @@ class SharedMount extends MountPoint implements MoveableMount { /** * @param string $storage - * @param string $mountpoint + * @param SharedMount[] $mountpoints * @param array|null $arguments * @param \OCP\Files\Storage\IStorageFactory $loader */ - public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { + public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) { $this->user = $arguments['user']; $this->recipientView = new View('/' . $this->user . '/files'); - $newMountPoint = $this->verifyMountPoint($arguments['share']); + $newMountPoint = $this->verifyMountPoint($arguments['share'], $mountpoints); $absMountPoint = '/' . $this->user . '/files' . $newMountPoint; $arguments['ownerView'] = new View('/' . $arguments['share']['uid_owner'] . '/files'); parent::__construct($storage, $absMountPoint, $arguments, $loader); @@ -67,9 +68,10 @@ class SharedMount extends MountPoint implements MoveableMount { * check if the parent folder exists otherwise move the mount point up * * @param array $share + * @param SharedMount[] $mountpoints * @return string */ - private function verifyMountPoint(&$share) { + private function verifyMountPoint(&$share, array $mountpoints) { $mountPoint = basename($share['file_target']); $parent = dirname($share['file_target']); @@ -78,10 +80,10 @@ class SharedMount extends MountPoint implements MoveableMount { $parent = Helper::getShareFolder(); } - $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget( + $newMountPoint = $this->generateUniqueTarget( \OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), - [], - $this->recipientView + $this->recipientView, + $mountpoints ); if ($newMountPoint !== $share['file_target']) { @@ -94,6 +96,37 @@ class SharedMount extends MountPoint implements MoveableMount { } /** + * @param string $path + * @param View $view + * @param SharedMount[] $mountpoints + * @return mixed + */ + private function generateUniqueTarget($path, $view, array $mountpoints) { + $pathinfo = pathinfo($path); + $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; + $name = $pathinfo['filename']; + $dir = $pathinfo['dirname']; + + // Helper function to find existing mount points + $mountpointExists = function($path) use ($mountpoints) { + foreach ($mountpoints as $mountpoint) { + if ($mountpoint->getShare()['file_target'] === $path) { + return true; + } + } + return false; + }; + + $i = 2; + while ($view->file_exists($path) || $mountpointExists($path)) { + $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); + $i++; + } + + return $path; + } + + /** * update fileTarget in the database if the mount point changed * * @param string $newPath diff --git a/apps/updatenotification/appinfo/app.php b/apps/updatenotification/appinfo/app.php index f257cba6974..a88861c0942 100644 --- a/apps/updatenotification/appinfo/app.php +++ b/apps/updatenotification/appinfo/app.php @@ -20,10 +20,9 @@ */ if(\OC::$server->getConfig()->getSystemValue('updatechecker', true) === true) { - $updater = new \OC\Updater( - \OC::$server->getHTTPHelper(), - \OC::$server->getConfig(), - \OC::$server->getIntegrityCodeChecker() + $updater = new \OC\Updater\VersionCheck( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig() ); $updateChecker = new \OCA\UpdateNotification\UpdateChecker( $updater diff --git a/apps/updatenotification/appinfo/application.php b/apps/updatenotification/appinfo/application.php index 24c0a11af69..08ff4abf766 100644 --- a/apps/updatenotification/appinfo/application.php +++ b/apps/updatenotification/appinfo/application.php @@ -34,10 +34,9 @@ class Application extends App { $container = $this->getContainer(); $container->registerService('AdminController', function(IAppContainer $c) { - $updater = new \OC\Updater( - \OC::$server->getHTTPHelper(), - \OC::$server->getConfig(), - \OC::$server->getIntegrityCodeChecker() + $updater = new \OC\Updater\VersionCheck( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig() ); return new AdminController( $c->query('AppName'), diff --git a/apps/updatenotification/lib/updatechecker.php b/apps/updatenotification/lib/updatechecker.php index 965e21617e7..bf653c23b8f 100644 --- a/apps/updatenotification/lib/updatechecker.php +++ b/apps/updatenotification/lib/updatechecker.php @@ -21,16 +21,16 @@ namespace OCA\UpdateNotification; -use OC\Updater; +use OC\Updater\VersionCheck; class UpdateChecker { - /** @var Updater */ + /** @var VersionCheck */ private $updater; /** - * @param Updater $updater + * @param VersionCheck $updater */ - public function __construct(Updater $updater) { + public function __construct(VersionCheck $updater) { $this->updater = $updater; } diff --git a/apps/updatenotification/tests/UpdateCheckerTest.php b/apps/updatenotification/tests/UpdateCheckerTest.php index 9591758c4c9..5865284a48e 100644 --- a/apps/updatenotification/tests/UpdateCheckerTest.php +++ b/apps/updatenotification/tests/UpdateCheckerTest.php @@ -34,7 +34,7 @@ class UpdateCheckerTest extends TestCase { public function setUp() { parent::setUp(); - $this->updater = $this->getMockBuilder('\OC\Updater') + $this->updater = $this->getMockBuilder('\OC\Updater\VersionCheck') ->disableOriginalConstructor()->getMock(); $this->updateChecker = new UpdateChecker($this->updater); } diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php index daec2bed13a..418a2bfc015 100644 --- a/apps/user_ldap/lib/configuration.php +++ b/apps/user_ldap/lib/configuration.php @@ -28,6 +28,9 @@ namespace OCA\user_ldap\lib; +/** + * @property int ldapPagingSize holds an integer + */ class Configuration { protected $configPrefix = null; diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index c485ac74395..53c9b3790a7 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -85,11 +85,12 @@ class Connection extends LDAPUtility { if($memcache->isAvailable()) { $this->cache = $memcache->create(); } - $this->hasPagedResultSupport = - $this->ldap->hasPagedResultSupport(); $helper = new Helper(); $this->doNotValidate = !in_array($this->configPrefix, $helper->getServerConfigurationPrefixes()); + $this->hasPagedResultSupport = + intval($this->configuration->ldapPagingSize) !== 0 + || $this->ldap->hasPagedResultSupport(); } public function __destruct() { diff --git a/autotest-external.sh b/autotest-external.sh index ef6516c0721..9705980aa2b 100755 --- a/autotest-external.sh +++ b/autotest-external.sh @@ -178,7 +178,7 @@ EOF return; fi - FILES_EXTERNAL_BACKEND_PATH=../apps/files_external/tests/backends + FILES_EXTERNAL_BACKEND_PATH=../apps/files_external/tests/storage FILES_EXTERNAL_BACKEND_ENV_PATH=../apps/files_external/tests/env for startFile in `ls -1 $FILES_EXTERNAL_BACKEND_ENV_PATH | grep start`; do @@ -198,16 +198,17 @@ EOF # getting backend to test from filename # it's the part between the dots startSomething.TestToRun.sh testToRun=`echo $startFile | cut -d '-' -f 2` + testToRun="${testToRun}test.php" # run the specific test if [ -z "$NOCOVERAGE" ]; then rm -rf "coverage-external-html-$1-$name" mkdir "coverage-external-html-$1-$name" - "$PHPUNIT" --configuration phpunit-autotest-external.xml --log-junit "autotest-external-results-$1-$name.xml" --coverage-clover "autotest-external-clover-$1-$name.xml" --coverage-html "coverage-external-html-$1-$name" "$FILES_EXTERNAL_BACKEND_PATH/$testToRun.php" + "$PHPUNIT" --configuration phpunit-autotest-external.xml --log-junit "autotest-external-results-$1-$name.xml" --coverage-clover "autotest-external-clover-$1-$name.xml" --coverage-html "coverage-external-html-$1-$name" "$FILES_EXTERNAL_BACKEND_PATH/$testToRun" RESULT=$? else echo "No coverage" - "$PHPUNIT" --configuration phpunit-autotest-external.xml --log-junit "autotest-external-results-$1-$name.xml" "$FILES_EXTERNAL_BACKEND_PATH/$testToRun.php" + "$PHPUNIT" --configuration phpunit-autotest-external.xml --log-junit "autotest-external-results-$1-$name.xml" "$FILES_EXTERNAL_BACKEND_PATH/$testToRun" RESULT=$? fi else diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index 2ef5f252f11..79c447ac573 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -100,6 +100,25 @@ trait WebDav { } /** + * @When /^Downloading last public shared file inside a folder "([^"]*)" with range "([^"]*)"$/ + * @param string $range + */ + public function downloadPublicFileInsideAFolderWithRange($path, $range){ + $token = $this->lastShareData->data->token; + $fullUrl = substr($this->baseUrl, 0, -4) . "public.php/webdav" . "$path"; + $headers['Range'] = $range; + + $client = new GClient(); + $options = []; + $options['auth'] = [$token, ""]; + + $request = $client->createRequest("GET", $fullUrl, $options); + $request->addHeader('Range', $range); + + $this->response = $client->send($request); + } + + /** * @Then /^Downloaded content should be "([^"]*)"$/ * @param string $content */ @@ -373,5 +392,37 @@ trait WebDav { $this->makeDavRequest($user, 'PUT', $file, ['OC-Chunked' => '1'], $data); } + /** + * @Given user :user creates a new chunking upload with id :id + */ + public function userCreatesANewChunkingUploadWithId($user, $id) + { + $destination = '/uploads/'.$user.'/'.$id; + $this->makeDavRequest($user, 'MKCOL', $destination, []); + } + + /** + * @Given user :user uploads new chunk file :num with :data to id :id + */ + public function userUploadsNewChunkFileOfWithToId($user, $num, $data, $id) + { + $data = \GuzzleHttp\Stream\Stream::factory($data); + $destination = '/uploads/'.$user.'/'.$id.'/'.$num; + $this->makeDavRequest($user, 'PUT', $destination, [], $data); + } + + /** + * @Given user :user moves new chunk file with id :id to :dest + */ + public function userMovesNewChunkFileWithIdToMychunkedfile($user, $id, $dest) + { + $source = '/uploads/'.$user.'/'.$id.'/.file'; + $destination = substr($this->baseUrl, 0, -4) . $this->davPath . '/files/'.$user.$dest; + $this->makeDavRequest($user, 'MOVE', $source, [ + 'Destination' => $destination + ]); + } + + } diff --git a/build/integration/features/sharing-v1.feature b/build/integration/features/sharing-v1.feature index 83b72cc7449..49c2dbf58c6 100644 --- a/build/integration/features/sharing-v1.feature +++ b/build/integration/features/sharing-v1.feature @@ -251,6 +251,20 @@ Feature: sharing And User "user2" should be included in the response And User "user3" should not be included in the response + Scenario: Reshared files can be still accessed if a user in the middle removes it. + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user3" exists + And file "textfile0.txt" of user "user0" is shared with user "user1" + And file "textfile0 (2).txt" of user "user1" is shared with user "user2" + And file "textfile0 (2).txt" of user "user2" is shared with user "user3" + And As an "user1" + When User "user1" deletes file "/textfile0 (2).txt" + And As an "user3" + And Downloading file "/textfile0 (2).txt" with range "bytes=1-7" + Then Downloaded content should be "wnCloud" + Scenario: getting share info of a share Given user "user0" exists And user "user1" exists @@ -571,8 +585,8 @@ Feature: sharing Given user "user0" exists And User "user0" uploads file with content "foo" to "/tmp.txt" When as "user0" gets properties of folder "/tmp.txt" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "19" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "19" Scenario: Correct webdav share-permissions for received file with edit and reshare permissions Given user "user0" exists @@ -580,8 +594,8 @@ Feature: sharing And User "user0" uploads file with content "foo" to "/tmp.txt" And file "tmp.txt" of user "user0" is shared with user "user1" When as "user1" gets properties of folder "/tmp.txt" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "19" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "19" Scenario: Correct webdav share-permissions for received file with edit permissions but no reshare permissions Given user "user0" exists @@ -592,8 +606,8 @@ Feature: sharing And Updating last share with | permissions | 3 | When as "user1" gets properties of folder "/tmp.txt" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "3" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "3" Scenario: Correct webdav share-permissions for received file with reshare permissions but no edit permissions Given user "user0" exists @@ -604,15 +618,15 @@ Feature: sharing And Updating last share with | permissions | 17 | When as "user1" gets properties of folder "/tmp.txt" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "17" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "17" Scenario: Correct webdav share-permissions for owned folder Given user "user0" exists And user "user0" created a folder "/tmp" When as "user0" gets properties of folder "/" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "31" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "31" Scenario: Correct webdav share-permissions for received folder with all permissions Given user "user0" exists @@ -620,8 +634,8 @@ Feature: sharing And user "user0" created a folder "/tmp" And file "/tmp" of user "user0" is shared with user "user1" When as "user1" gets properties of folder "/tmp" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "31" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "31" Scenario: Correct webdav share-permissions for received folder with all permissions but edit Given user "user0" exists @@ -632,8 +646,8 @@ Feature: sharing And Updating last share with | permissions | 29 | When as "user1" gets properties of folder "/tmp" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "29" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "29" Scenario: Correct webdav share-permissions for received folder with all permissions but create Given user "user0" exists @@ -644,8 +658,8 @@ Feature: sharing And Updating last share with | permissions | 27 | When as "user1" gets properties of folder "/tmp" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "27" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "27" Scenario: Correct webdav share-permissions for received folder with all permissions but delete Given user "user0" exists @@ -656,8 +670,8 @@ Feature: sharing And Updating last share with | permissions | 23 | When as "user1" gets properties of folder "/tmp" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "23" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "23" Scenario: Correct webdav share-permissions for received folder with all permissions but share Given user "user0" exists @@ -668,5 +682,17 @@ Feature: sharing And Updating last share with | permissions | 15 | When as "user1" gets properties of folder "/tmp" with - |{http://owncloud.org/ns}share-permissions| - Then the single response should contain a property "{http://owncloud.org/ns}share-permissions" with value "15" + |{http://open-collaboration-services.org/ns}share-permissions | + Then the single response should contain a property "{http://open-collaboration-services.org/ns}share-permissions" with value "15" + + Scenario: unique target names for incomming shares + Given user "user0" exists + And user "user1" exists + And user "user2" exists + And user "user0" created a folder "/foo" + And user "user1" created a folder "/foo" + When file "/foo" of user "user0" is shared with user "user2" + And file "/foo" of user "user1" is shared with user "user2" + Then user "user2" should see following elements + | /foo/ | + | /foo%20(2)/ | diff --git a/build/integration/features/webdav-related.feature b/build/integration/features/webdav-related.feature index ee841f9eb5b..abdc63935e9 100644 --- a/build/integration/features/webdav-related.feature +++ b/build/integration/features/webdav-related.feature @@ -68,13 +68,22 @@ Feature: webdav-related And Downloading last public shared file with range "bytes=51-77" Then Downloaded content should be "example file for developers" + Scenario: download a public shared file inside a folder with range + Given user "user0" exists + And As an "user0" + When creating a share with + | path | PARENT | + | shareType | 3 | + And Downloading last public shared file inside a folder "/parent.txt" with range "bytes=1-7" + Then Downloaded content should be "wnCloud" + Scenario: Downloading a file on the old endpoint should serve security headers Given using dav path "remote.php/webdav" And As an "admin" When Downloading file "/welcome.txt" Then The following headers should be set |Content-Disposition|attachment| - |Content-Security-Policy|default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *| + |Content-Security-Policy|default-src 'none';| |X-Content-Type-Options |nosniff| |X-Download-Options|noopen| |X-Frame-Options|Sameorigin| @@ -89,7 +98,7 @@ Feature: webdav-related When Downloading file "/welcome.txt" Then The following headers should be set |Content-Disposition|attachment| - |Content-Security-Policy|default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src *; img-src * data: blob:; font-src 'self' data:; media-src *; connect-src *| + |Content-Security-Policy|default-src 'none';| |X-Content-Type-Options |nosniff| |X-Download-Options|noopen| |X-Frame-Options|Sameorigin| @@ -241,3 +250,39 @@ Feature: webdav-related | 0 | | 1 | | 3 | + + Scenario: Upload chunked file asc with new chunking + Given using dav path "remote.php/dav" + And user "user0" exists + And user "user0" creates a new chunking upload with id "chunking-42" + And user "user0" uploads new chunk file "1" with "AAAAA" to id "chunking-42" + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" + And user "user0" moves new chunk file with id "chunking-42" to "/myChunkedFile.txt" + When As an "user0" + And Downloading file "/files/user0/myChunkedFile.txt" + Then Downloaded content should be "AAAAABBBBBCCCCC" + + Scenario: Upload chunked file desc with new chunking + Given using dav path "remote.php/dav" + And user "user0" exists + And user "user0" creates a new chunking upload with id "chunking-42" + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" + And user "user0" uploads new chunk file "1" with "AAAAA" to id "chunking-42" + And user "user0" moves new chunk file with id "chunking-42" to "/myChunkedFile.txt" + When As an "user0" + And Downloading file "/files/user0/myChunkedFile.txt" + Then Downloaded content should be "AAAAABBBBBCCCCC" + + Scenario: Upload chunked file random with new chunking + Given using dav path "remote.php/dav" + And user "user0" exists + And user "user0" creates a new chunking upload with id "chunking-42" + And user "user0" uploads new chunk file "2" with "BBBBB" to id "chunking-42" + And user "user0" uploads new chunk file "3" with "CCCCC" to id "chunking-42" + And user "user0" uploads new chunk file "1" with "AAAAA" to id "chunking-42" + And user "user0" moves new chunk file with id "chunking-42" to "/myChunkedFile.txt" + When As an "user0" + And Downloading file "/files/user0/myChunkedFile.txt" + Then Downloaded content should be "AAAAABBBBBCCCCC" diff --git a/config/config.sample.php b/config/config.sample.php index d1ad1cd38d7..b54bbf6a7b9 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -430,14 +430,14 @@ $CONFIG = array( * Both minimum and maximum times can be set together to explicitly define * version deletion. For migration purposes, this setting is installed * initially set to "auto", which is equivalent to the default setting in - * ownCloud 8.1 and before. + * ownCloud 8.1 and before. * * Available values: * * * ``auto`` * default setting. Automatically expire versions according to expire - * rules. Please refer to Files_versions online documentation for more - * info. + * rules. Please refer to :doc:`../configuration_files/file_versioning` for + * more information. * * ``D, auto`` * keep versions at least for D days, apply expire rules to all versions * that are older than D days @@ -612,21 +612,6 @@ $CONFIG = array( */ /** - * ownCloud uses some 3rd party PHP components to provide certain functionality. - * These components are shipped as part of the software package and reside in - * ``owncloud/3rdparty``. Use this option to configure a different location. - * For example, if your location is /var/www/owncloud/foo/3rdparty, then the - * correct configuration is '3rdpartyroot' => '/var/www/owncloud/foo/', - */ -'3rdpartyroot' => '', - -/** - * If you have an alternate ``3rdpartyroot``, you must also configure the URL as - * seen by a Web browser. - */ -'3rdpartyurl' => '', - -/** * This section is for configuring the download links for ownCloud clients, as * seen in the first-run wizard and on Personal pages. */ @@ -740,7 +725,7 @@ $CONFIG = array( */ 'preview_office_cl_parameters' => ' --headless --nologo --nofirststartwizard --invisible --norestore '. - '-convert-to pdf -outdir ', + '--convert-to pdf --outdir ', /** * Only register providers that have been explicitly enabled @@ -1212,6 +1197,11 @@ $CONFIG = array( 'memcache.locking' => '\\OC\\Memcache\\Redis', /** + * Disable the web based updater + */ +'upgrade.disable-web' => false, + +/** * Set this ownCloud instance to debugging mode * * Only enable this for local development and not in production environments diff --git a/core/Application.php b/core/Application.php index 30376ee4f2e..0a54386a2ce 100644 --- a/core/Application.php +++ b/core/Application.php @@ -28,6 +28,7 @@ namespace OC\Core; use OC\AppFramework\Utility\SimpleContainer; use OC\AppFramework\Utility\TimeFactory; +use OC\Core\Controller\LoginController; use \OCP\AppFramework\App; use OC\Core\Controller\LostController; use OC\Core\Controller\UserController; @@ -89,6 +90,17 @@ class Application extends App { $c->query('Logger') ); }); + $container->registerService('LoginController', function(SimpleContainer $c) { + return new LoginController( + $c->query('AppName'), + $c->query('Request'), + $c->query('UserManager'), + $c->query('Config'), + $c->query('Session'), + $c->query('UserSession'), + $c->query('URLGenerator') + ); + }); /** * Core class wrappers @@ -114,6 +126,9 @@ class Application extends App { $container->registerService('AvatarManager', function(SimpleContainer $c) { return $c->query('ServerContainer')->getAvatarManager(); }); + $container->registerService('Session', function(SimpleContainer $c) { + return $c->query('ServerContainer')->getSession(); + }); $container->registerService('UserSession', function(SimpleContainer $c) { return $c->query('ServerContainer')->getUserSession(); }); diff --git a/core/Command/Upgrade.php b/core/Command/Upgrade.php index cbb1f26f938..1001962c6af 100644 --- a/core/Command/Upgrade.php +++ b/core/Command/Upgrade.php @@ -128,7 +128,6 @@ class Upgrade extends Command { $self = $this; $updater = new Updater( - \OC::$server->getHTTPHelper(), $this->config, \OC::$server->getIntegrityCodeChecker(), $this->logger diff --git a/core/Controller/LoginController.php b/core/Controller/LoginController.php new file mode 100644 index 00000000000..796706d364a --- /dev/null +++ b/core/Controller/LoginController.php @@ -0,0 +1,160 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Core\Controller; + +use OC\Setup; +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IRequest; +use OCP\ISession; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\IUserManager; +use OCP\IUserSession; + +class LoginController extends Controller { + /** @var IUserManager */ + private $userManager; + /** @var IConfig */ + private $config; + /** @var ISession */ + private $session; + /** @var IUserSession */ + private $userSession; + /** @var IURLGenerator */ + private $urlGenerator; + + /** + * @param string $appName + * @param IRequest $request + * @param IUserManager $userManager + * @param IConfig $config + * @param ISession $session + * @param IUserSession $userSession + * @param IURLGenerator $urlGenerator + */ + function __construct($appName, + IRequest $request, + IUserManager $userManager, + IConfig $config, + ISession $session, + IUserSession $userSession, + IURLGenerator $urlGenerator) { + parent::__construct($appName, $request); + $this->userManager = $userManager; + $this->config = $config; + $this->session = $session; + $this->userSession = $userSession; + $this->urlGenerator = $urlGenerator; + } + + /** + * @NoAdminRequired + * @UseSession + * + * @return RedirectResponse + */ + public function logout() { + $loginToken = $this->request->getCookie('oc_token'); + if (!is_null($loginToken)) { + $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken); + } + $this->userSession->logout(); + + return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm')); + } + + /** + * @PublicPage + * @NoCSRFRequired + * @UseSession + * + * @param string $user + * @param string $redirect_url + * @param string $remember_login + * + * @return TemplateResponse + */ + public function showLoginForm($user, + $redirect_url, + $remember_login) { + if($this->userSession->isLoggedIn()) { + return new RedirectResponse(\OC_Util::getDefaultPageUrl()); + } + + $parameters = array(); + $loginMessages = $this->session->get('loginMessages'); + $errors = []; + $messages = []; + if(is_array($loginMessages)) { + list($errors, $messages) = $loginMessages; + } + $this->session->remove('loginMessages'); + foreach ($errors as $value) { + $parameters[$value] = true; + } + + $parameters['messages'] = $messages; + if (!is_null($user) && $user !== '') { + $parameters['loginName'] = $user; + $parameters['user_autofocus'] = false; + } else { + $parameters['loginName'] = ''; + $parameters['user_autofocus'] = true; + } + if (!empty($redirect_url)) { + $parameters['redirect_url'] = $redirect_url; + } + + $parameters['canResetPassword'] = true; + if (!$this->config->getSystemValue('lost_password_link')) { + if (!is_null($user) && $user !== '') { + $userObj = $this->userManager->get($user); + if ($userObj instanceof IUser) { + $parameters['canResetPassword'] = $userObj->canChangePassword(); + } + } + } + + $parameters['alt_login'] = \OC_App::getAlternativeLogIns(); + $parameters['rememberLoginAllowed'] = \OC_Util::rememberLoginAllowed(); + $parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0; + + if (!is_null($user) && $user !== '') { + $parameters['loginName'] = $user; + $parameters['user_autofocus'] = false; + } else { + $parameters['loginName'] = ''; + $parameters['user_autofocus'] = true; + } + + return new TemplateResponse( + $this->appName, + 'login', + $parameters, + 'guest' + ); + } + +} diff --git a/core/ajax/update.php b/core/ajax/update.php index 631a8a7871c..4bc1f4faa45 100644 --- a/core/ajax/update.php +++ b/core/ajax/update.php @@ -37,9 +37,17 @@ $eventSource = \OC::$server->createEventSource(); // need to send an initial message to force-init the event source, // which will then trigger its own CSRF check and produces its own CSRF error // message -$eventSource->send('success', (string)$l->t('Preparing update')); +//$eventSource->send('success', (string)$l->t('Preparing update')); if (OC::checkUpgrade(false)) { + + $config = \OC::$server->getSystemConfig(); + if ($config->getValue('upgrade.disable-web', true)) { + $eventSource->send('failure', (string)$l->t('Updates need to be installed. Please use the command line updater.')); + $eventSource->close(); + exit(); + } + // if a user is currently logged in, their session must be ignored to // avoid side effects \OC_User::setIncognitoMode(true); @@ -47,7 +55,6 @@ if (OC::checkUpgrade(false)) { $logger = \OC::$server->getLogger(); $config = \OC::$server->getConfig(); $updater = new \OC\Updater( - \OC::$server->getHTTPHelper(), $config, \OC::$server->getIntegrityCodeChecker(), $logger diff --git a/core/css/header.css b/core/css/header.css index 5a5acb269ab..083f6f350ea 100644 --- a/core/css/header.css +++ b/core/css/header.css @@ -294,6 +294,12 @@ color: #bbb; cursor: pointer; } +#settings .icon-loading-dark { + display: inline-block; + margin-bottom: -3px; + margin-right: 6px; + background-size: 16px 16px; +} #expand { display: block; padding: 7px 30px 6px 10px; diff --git a/core/css/styles.css b/core/css/styles.css index a1dda59a86b..20f66eee25b 100644 --- a/core/css/styles.css +++ b/core/css/styles.css @@ -25,12 +25,10 @@ body { #body-login { text-align: center; - background: #1d2d44; /* Old browsers */ - background: -moz-linear-gradient(top, #35537a 0%, #1d2d44 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#35537a), color-stop(100%,#1d2d44)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, #35537a 0%,#1d2d44 100%); /* Chrome10+,Safari5.1+ */ - background: linear-gradient(top, #35537a 0%,#1d2d44 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#35537a', endColorstr='#1d2d44',GradientType=0 ); /* IE6-9 */ + background-image: url('../img/background.jpg'); + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: cover; } .float-spinner { @@ -223,9 +221,7 @@ body { #body-login form fieldset .warning-info, #body-login form input[type="checkbox"]+label { text-align: center; - color: #ccc; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)"; - opacity: .6; + color: #fff; } /* overrides another !important statement that sets this to unreadable black */ #body-login form .warning input[type="checkbox"]:hover+label, @@ -421,24 +417,21 @@ html.ie8 #body-login form input[type="checkbox"] { #body-login form .errors { background:#fed7d7; border:1px solid #f00; list-style-indent:inside; margin:0 0 2em; padding:1em; } #body-login .success { background:#d7fed7; border:1px solid #0f0; width: 35%; margin: 30px auto; padding:1em; text-align: center;} -#body-login #remember_login:hover+label, -#body-login #remember_login:focus+label { - color: #fff !important; -} - #body-login #showAdvanced > img { padding: 4px; box-sizing: border-box; } #body-login p.info a, #body-login #showAdvanced { - color: #ccc; -} - -#body-login p.info a:hover, #body-login p.info a:focus { color: #fff; } +#body-login #remember_login:hover+label, +#body-login #remember_login:focus+label, +#body-login p.info a:hover, +#body-login p.info a:focus { + opacity: .6; +} #body-login footer .info { white-space: nowrap; @@ -618,8 +611,6 @@ html.ie8 #body-login form input[type="checkbox"] { } #remember_login { margin: 18px 5px 0 16px !important; - -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; - opacity: .7; } #body-login .remember-login-container { margin-top: 10px; diff --git a/core/css/tooltip.css b/core/css/tooltip.css index 34d0ec6c70f..3c3582e30ef 100644 --- a/core/css/tooltip.css +++ b/core/css/tooltip.css @@ -53,6 +53,7 @@ text-align: center; background-color: #000000; border-radius: 4px; + word-break: break-all; } .tooltip-arrow { position: absolute; diff --git a/core/img/background.jpg b/core/img/background.jpg Binary files differnew file mode 100644 index 00000000000..a4ede839cb5 --- /dev/null +++ b/core/img/background.jpg diff --git a/core/js/js.js b/core/js/js.js index 598e0dcd185..188c15c5db5 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1553,11 +1553,30 @@ function initCore() { } if(!event.ctrlKey) { $app.addClass('app-loading'); + } else { + // Close navigation when opening app in + // a new tab + OC.hideMenus(); + } + }); + } + + function setupUserMenu() { + var $menu = $('#header #settings'); + + $menu.delegate('a', 'click', function(event) { + var $page = $(event.target); + if (!$page.is('a')) { + $page = $page.closest('a'); } + $page.find('img').remove(); + $page.find('div').remove(); // prevent odd double-clicks + $page.prepend($('<div/>').addClass('icon-loading-dark')); }); } setupMainMenu(); + setupUserMenu(); // move triangle of apps dropdown to align with app name triangle // 2 is the additional offset between the triangles diff --git a/core/js/placeholder.js b/core/js/placeholder.js index da721ac5bcb..1b03a28ecca 100644 --- a/core/js/placeholder.js +++ b/core/js/placeholder.js @@ -92,7 +92,7 @@ // Init vars var result = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; var rgb = [0, 0, 0]; - var sat = 80; + var sat = 70; var lum = 68; var modulo = 16; @@ -106,6 +106,12 @@ for(var count=1;count<modulo;count++) { rgb[count%3] += parseInt(result[count]); } + + // Reduce values bigger than rgb requirements + rgb[0] = rgb[0]%255; + rgb[1] = rgb[1]%255; + rgb[2] = rgb[2]%255; + var hsl = rgbToHsl(rgb[0], rgb[1], rgb[2]); // Classic formulla to check the brigtness for our eye diff --git a/core/l10n/cs_CZ.js b/core/l10n/cs_CZ.js index a627b824251..55d83f3a790 100644 --- a/core/l10n/cs_CZ.js +++ b/core/l10n/cs_CZ.js @@ -178,6 +178,7 @@ OC.L10N.register( "Share details could not be loaded for this item." : "Detaily sdílení pro tuto položku nelze načíst.", "No users or groups found for {search}" : "Nebyli nalezeni žádní členové ani skupiny pro {search}", "No users found for {search}" : "Nebyli nalezeni žádní uživatelé pro {search}", + "An error occurred. Please try again" : "Došlo k chybě. Zkuste to prosím znovu", "{sharee} (group)" : "{sharee} (skupina)", "{sharee} (at {server})" : "{sharee} (na {server})", "{sharee} (remote)" : "{sharee} (vzdálený)", @@ -211,6 +212,7 @@ OC.L10N.register( "new" : "nový", "_download %n file_::_download %n files_" : ["stáhnout %n soubor","stáhnout %n soubory","stáhnout %n souborů"], "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Probíhá aktualizace, opuštění této stránky může v některých prostředích přerušit proces.", + "Updating to {version}" : "Aktualizace na {version}", "An error occurred." : "Došlo k chybě.", "Please reload the page." : "Načtěte stránku znovu, prosím.", "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "Aktualizace nebyla úspěšná. Pro více informací si <a href=\"{url}\">přečtěte komentáře ve fóru</a> pojednávající o tomto problému.", @@ -275,6 +277,7 @@ OC.L10N.register( "Search" : "Hledat", "Server side authentication failed!" : "Autentizace na serveru selhala!", "Please contact your administrator." : "Kontaktujte prosím svého správce systému.", + "An internal error occurred." : "Nastala vnitřní chyba.", "Please try again or contact your administrator." : "Prosím zkuste to znovu nebo kontaktujte vašeho správce.", "Log in" : "Přihlásit", "Wrong password. Reset it?" : "Nesprávné heslo. Resetovat?", diff --git a/core/l10n/cs_CZ.json b/core/l10n/cs_CZ.json index a49a955dbbf..a73dca270f9 100644 --- a/core/l10n/cs_CZ.json +++ b/core/l10n/cs_CZ.json @@ -176,6 +176,7 @@ "Share details could not be loaded for this item." : "Detaily sdílení pro tuto položku nelze načíst.", "No users or groups found for {search}" : "Nebyli nalezeni žádní členové ani skupiny pro {search}", "No users found for {search}" : "Nebyli nalezeni žádní uživatelé pro {search}", + "An error occurred. Please try again" : "Došlo k chybě. Zkuste to prosím znovu", "{sharee} (group)" : "{sharee} (skupina)", "{sharee} (at {server})" : "{sharee} (na {server})", "{sharee} (remote)" : "{sharee} (vzdálený)", @@ -209,6 +210,7 @@ "new" : "nový", "_download %n file_::_download %n files_" : ["stáhnout %n soubor","stáhnout %n soubory","stáhnout %n souborů"], "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "Probíhá aktualizace, opuštění této stránky může v některých prostředích přerušit proces.", + "Updating to {version}" : "Aktualizace na {version}", "An error occurred." : "Došlo k chybě.", "Please reload the page." : "Načtěte stránku znovu, prosím.", "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "Aktualizace nebyla úspěšná. Pro více informací si <a href=\"{url}\">přečtěte komentáře ve fóru</a> pojednávající o tomto problému.", @@ -273,6 +275,7 @@ "Search" : "Hledat", "Server side authentication failed!" : "Autentizace na serveru selhala!", "Please contact your administrator." : "Kontaktujte prosím svého správce systému.", + "An internal error occurred." : "Nastala vnitřní chyba.", "Please try again or contact your administrator." : "Prosím zkuste to znovu nebo kontaktujte vašeho správce.", "Log in" : "Přihlásit", "Wrong password. Reset it?" : "Nesprávné heslo. Resetovat?", diff --git a/core/l10n/fr.js b/core/l10n/fr.js index 8f333a1e23e..9bab48c455b 100644 --- a/core/l10n/fr.js +++ b/core/l10n/fr.js @@ -210,6 +210,7 @@ OC.L10N.register( "new" : "Nouveau ", "_download %n file_::_download %n files_" : ["Télécharger %n fichier","Télécharger %n fichiers"], "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "La mise à jour est en cours. Selon la configuration, le fait de quitter cette page peut entraîner l'interruption de la procédure.", + "Updating to {version}" : "En cours de mise à jour vers la version {version}", "An error occurred." : "Une erreur est survenue.", "Please reload the page." : "Veuillez recharger la page.", "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "La mise à jour a échoué. Pour plus d'informations <a href=\"{url}\">consultez notre publication sur le forum</a> à propos de ce problème.", diff --git a/core/l10n/fr.json b/core/l10n/fr.json index 64f7312dd35..2f3d5c9542d 100644 --- a/core/l10n/fr.json +++ b/core/l10n/fr.json @@ -208,6 +208,7 @@ "new" : "Nouveau ", "_download %n file_::_download %n files_" : ["Télécharger %n fichier","Télécharger %n fichiers"], "The upgrade is in progress, leaving this page might interrupt the process in some environments." : "La mise à jour est en cours. Selon la configuration, le fait de quitter cette page peut entraîner l'interruption de la procédure.", + "Updating to {version}" : "En cours de mise à jour vers la version {version}", "An error occurred." : "Une erreur est survenue.", "Please reload the page." : "Veuillez recharger la page.", "The update was unsuccessful. For more information <a href=\"{url}\">check our forum post</a> covering this issue." : "La mise à jour a échoué. Pour plus d'informations <a href=\"{url}\">consultez notre publication sur le forum</a> à propos de ce problème.", diff --git a/core/l10n/hu_HU.js b/core/l10n/hu_HU.js index 11e3314f1a9..787ab79e516 100644 --- a/core/l10n/hu_HU.js +++ b/core/l10n/hu_HU.js @@ -1,7 +1,7 @@ OC.L10N.register( "core", { - "Please select a file." : "Kérjük, válasszon egy fájlt.", + "Please select a file." : "Kérjük, válasszon ki egy fájlt.", "File is too big" : "A fájl túl nagy", "Invalid file provided" : "Érvénytelen fájl van megadva", "No image or file provided" : "Nincs kép vagy fájl megadva", @@ -98,6 +98,7 @@ OC.L10N.register( "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Problémák vannak a kódintegritás ellenőrzéssel. Bővebb információ…</a>", "Settings" : "Beállítások", "Saving..." : "Mentés...", + "Dismiss" : "Elutasít", "seconds ago" : "pár másodperce", "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "A jelszó felülírásához a linket e-mailben elküldtük. Ha a levél elfogadható időn belül nem érkezik meg, ellenőrizze a spam/levélszemét mappát.<br>Ha nincs ott, kérdezze meg a helyi rendszergazdát.", "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Az Ön állományai titkosítva vannak. Ha nem engedélyezte korábban az adatok visszanyeréséhez szükséges kulcs használatát, akkor a jelszó megváltoztatását követően nem fog hozzáférni az adataihoz. Ha nem biztos abban, hogy mit kellene tennie, akkor kérdezze meg a rendszergazdát, mielőtt továbbmenne.<br />Biztos, hogy folytatni kívánja?", @@ -127,11 +128,19 @@ OC.L10N.register( "Good password" : "Jó jelszó", "Strong password" : "Erős jelszó", "Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "A webszerver nincs megfelelően beállítva a fájl szinkronizációhoz, mert a WebDAV interfész nem működik.", + "Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "A webszerver nincs jól beállítva, hogy kiszolgálja a(z) „{url}” hivatkozást. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Ennek a szervernek nincs működő internet kapcsolata. Ez azt jelenti, hogy néhány tulajdonság, mint pl. külső tárolók felcsatolása, frissítési értesítések, vagy egyéb alkalmazások nem működnek. A fájlok távoli elérése és az e-mail értesítések is lehet, hogy nem működnek. Ajánlott az internet kapcsolat engedélyezése a szerveren, ha minden tulajdonságot használni szeretne.", + "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Nincs memória gyorsítótár beállítva. A teljesítmény növelése érdekében kérjük állítsa be a memcache-t, ha elérhető. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", + "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "/dev/urandom nem olvasható a PHP számára, mely nagy biztonsági probléma. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", + "You are currently running PHP {version}. We encourage you to upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "Jelenleg {version} PHP verziót használ. Javasoljuk, hogy frissítse a PHP verziót, hogy kihasználhassa a <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">teljesítménybeli és a biztonságbeli előnyöket, amiket a PHP csoport kínál</a>, amilyen hamar a disztribúciója támogatja.", + "The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "A fordított proxy fejlécek konfigurációs beállításai helytelenek, vagy egy megbízható proxy-ból próbálja az ownCloud-ot elérni. Ha nem megbízható proxy-ból próbálja elérni az ownCloud-ot, akkor ez egy biztonsági probléma, a támadó az ownCloud számára látható IP cím csalást tud végrehajtani. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", + "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "Memcached be van konfigurálva gyorsítótárnak, de rossz \"memcache\" PHP modul van telepítve. \\OC\\Memcache\\Memcached csak a \"memcached\"-t támogatja, és nem a \"memcache\"-t. Kérjük, nézze meg a <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki oldalt a modulokkal kapcsolatban</a>.", + "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Néhány fájl nem felelt meg az integritás ellenőrzésen. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat. (<a href=\"{codeIntegrityDownloadEndpoint}\">Érvénytelen fájlok listája…</a> / <a href=\"{rescanEndpoint}\">Újra ellenőrzés…</a>)", "Error occurred while checking server setup" : "Hiba történt a szerver beállítások ellenőrzése közben", "Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Az adat könyvtára és a fájljai valószínűleg elérhetőek az internetről, mert a .htaccess fájl nem működik. Erősen ajánlott, hogy úgy állítsa be a webszerverét, hogy az adatkönyvtár ne legyen elérhető az internetről, vagy mozgassa ki az adatokat a webszerver gyökérkönyvtárából.", "The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "A \"{header}\" HTTP fejléc nincs beállítva, hogy megegyezzen az elvárttal \"{expected}\". Ez egy potenciális biztonsági kockázat és kérjük, hogy változtassa meg a beállításokat.", - "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Jelenleg HTTP-vel éri el a weboldalt. Nagyon ajánlott a HTTPS konfiguráció használata ehelyett, ahogyan ezt részleteztük a <a href=\"{docUrl}\">biztonsági tippek</a> dokumentációban", + "The \"Strict-Transport-Security\" HTTP header is not configured to at least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\" rel=\"noreferrer\">security tips</a>." : "A \"Strict-Transport-Security\" HTTP fejléc nincs beállítva hogy \"{seconds}\" másodpercig tartson. Biztonsági okokból ajánljuk, hogy engedélyezze a HSTS, ahogyan ezt részletezzük a <a href=\"{docUrl}\" rel=\"noreferrer\">biztonsági tippek</a> dokumentációban.", + "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Jelenleg HTTP-vel éri el a weboldalt. Erősen ajánlott a HTTPS konfiguráció használata ehelyett, ahogyan ezt részleteztük a <a href=\"{docUrl}\">biztonsági tippek</a> dokumentációban", "Shared" : "Megosztott", "Shared with {recipients}" : "Megosztva ővelük: {recipients}", "Error" : "Hiba", @@ -147,7 +156,7 @@ OC.L10N.register( "Email sent" : "Az e-mailt elküldtük!", "Resharing is not allowed" : "Ezt az állományt csak a tulajdonosa oszthatja meg másokkal", "Share link" : "Megosztás hivatkozással", - "Link" : "Link", + "Link" : "Hivatkozás", "Password protect" : "Jelszóval védett", "Password" : "Jelszó", "Allow editing" : "Szerkesztés engedélyezése", @@ -174,7 +183,7 @@ OC.L10N.register( "{sharee} (at {server})" : "{sharee} ({server} szerveren)", "{sharee} (remote)" : "{sharee} (távoli)", "Share" : "Megosztás", - "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Megosztás más ownCloud szerverekkel, a következő formátum használatával felhasznalo@példa.com/owncloud", + "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Megosztás más ownCloud szerverekkel, a következő formátum használatával felhasználó@példa.hu/owncloud", "Share with users…" : "Megosztás felhasználókkal", "Share with users, groups or remote users…" : "Megosztás felhasználókkal, csoportokkal vagy távoli felhasználókkal...", "Share with users or groups…" : "Megosztás felhasználókkal vagy csoportokkal...", @@ -188,6 +197,7 @@ OC.L10N.register( "({scope})" : "({scope})", "Delete" : "Törlés", "Rename" : "Átnevezés", + "Collaborative tags" : "Címke hozzárendelése", "The object type is not specified." : "Az objektum típusa nincs megadva.", "Enter new" : "Új beírása", "Add" : "Hozzáadás", @@ -195,7 +205,7 @@ OC.L10N.register( "Error loading dialog template: {error}" : "Hiba a párbeszédpanel-sablon betöltésekor: {error}", "No tags selected for deletion." : "Nincs törlésre kijelölt címke.", "unknown text" : "ismeretlen szöveg", - "Hello world!" : "Üdv, világ!", + "Hello world!" : "Üdv, Világ!", "sunny" : "napos", "Hello {name}, the weather is {weather}" : "Üdv {name}, {weather} időnk van", "Hello {name}" : "Üdv {name}!", @@ -220,7 +230,7 @@ OC.L10N.register( "Access forbidden" : "A hozzáférés nem engedélyezett", "File not found" : "Fájl nem található", "The specified document has not been found on the server." : "A meghatározott dokumentum nem található a szerveren.", - "You can click here to return to %s." : "Ide kattintva visszatérhetsz ide: %s.", + "You can click here to return to %s." : "Ide kattintva visszatérhet ide: %s.", "Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" : "Üdvözöljük!\n\nÉrtesítjük, hogy %s megosztotta Önnel a következőt: %s.\nItt nézheti meg: %s\n\n", "The share will expire on %s." : "A megosztás lejár ekkor: %s.", "Cheers!" : "Üdv.", @@ -239,14 +249,15 @@ OC.L10N.register( "Trace" : "Lekövetés", "Security warning" : "Biztonsági figyelmeztetés", "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "Az adatkönyvtár és a benne levő állományok valószínűleg közvetlenül is elérhetők az internetről, mert a .htaccess állomány nem érvényesül.", - "Create an <strong>admin account</strong>" : "<strong>Rendszergazdai belépés</strong> létrehozása", + "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">documentation</a>." : "A kiszolgáló megfelelő beállításához kérjük olvassa el a <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">dokumentációt</a>.", + "Create an <strong>admin account</strong>" : "<strong>Rendszergazdai fiók</strong> létrehozása", "Username" : "Felhasználónév", - "Storage & database" : "Tárolás és adatbázis", + "Storage & database" : "Tárhely és adatbázis", "Data folder" : "Adatkönyvtár", "Configure the database" : "Adatbázis konfigurálása", "Only %s is available." : "Csak %s érhető el.", "Install and activate additional PHP modules to choose other database types." : "Telepítse és aktiválja a bővített PHP modulokat, hogy tudjon más adatbázis típust is kiválasztani.", - "For more details check out the documentation." : "További részletekért kérem ellenőrizze a dokumentációt.", + "For more details check out the documentation." : "További részletekért kérjük ellenőrizze a dokumentációt.", "Database user" : "Adatbázis felhasználónév", "Database password" : "Adatbázis jelszó", "Database name" : "Az adatbázis neve", @@ -261,13 +272,13 @@ OC.L10N.register( "Need help?" : "Segítségre van szüksége?", "See the documentation" : "Nézze meg a dokumentációt", "Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" : "Üdvözöljük!<br /><br />\n\nÉrtesítjük, hogy %s megosztotta Önnel a következőt: <strong>%s</strong><br />\n<a href=\"%s\">Itt nézheti meg.</a><br /><br />", - "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Az alkalmazás megfelelő működéséhez JavaScript szükséges. Kérjük {linkstart}engedélyezze a JavaScript-et{linkend} és frissítse a lapot.", - "Log out" : "Kilépés", + "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Az alkalmazás megfelelő működéséhez JavaScript szükséges. Kérjük, {linkstart}engedélyezze a JavaScript-et{linkend} és frissítse a lapot.", + "Log out" : "Kijelentkezés", "Search" : "Keresés", "Server side authentication failed!" : "A szerveroldali hitelesítés sikertelen!", "Please contact your administrator." : "Kérjük, lépjen kapcsolatba a rendszergazdával.", "An internal error occurred." : "Belső hiba történt.", - "Please try again or contact your administrator." : "Kérem próbálja újra, vagy vegye fel a kapcsolatot a rendszergazdával.", + "Please try again or contact your administrator." : "Kérjük, próbálja meg újra, vagy vegye fel a kapcsolatot a rendszergazdával.", "Log in" : "Bejelentkezés", "Wrong password. Reset it?" : "Hibás jelszó. Visszaállítja?", "Wrong password." : "Hibás jelszó.", @@ -284,17 +295,17 @@ OC.L10N.register( "You are accessing the server from an untrusted domain." : "A kiszolgálót nem megbízható domain névvel éri el.", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Kérjük keresse fel a rendszergazdát! Ha ennek a telepítésnek Ön a rendszergazdája, akkor állítsa be a config/config.php állományban a \"trusted_domain\" paramétert! A config/config.sample.php állományban talál példát a beállításra.", "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "A beállításoktól függően, rendszergazdaként lehetséges, hogy az alábbi gombot is használhatja a domain név megbízhatóvá tételéhez.", - "Add \"%s\" as trusted domain" : "Adjuk hozzá \"%s\"-t a megbízható domain nevekhez!", - "App update required" : "Alkalmazás frissítés szükséges", + "Add \"%s\" as trusted domain" : "Adjuk hozzá „%s”-t a megbízható domain nevekhez!", + "App update required" : "Alkalmazás frissítése szükséges", "%s will be updated to version %s" : "%s frissítve lesz erre a verzióra: %s", "These apps will be updated:" : "A következő alkalmazások lesznek frissítve:", "These incompatible apps will be disabled:" : "A követlező inkompatibilis alkalmazások tiltva lesznek:", - "The theme %s has been disabled." : "Ez a smink: %s letiltásra került.", - "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Kérjük gondoskodjon róla, hogy elmentse az adatbázist, a konfigurációs mappa és az adatamappa tartalmát, mielőtt folytatja.", + "The theme %s has been disabled." : "%s téma letiltásra került.", + "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Kérjük, gondoskodjon róla, hogy elmentse az adatbázist, a konfigurációs mappa és az adatmappa tartalmát, mielőtt folytatja.", "Start update" : "A frissítés megkezdése", - "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Nagyobb telepítések esetén úgy kerülhetők el az időtúllépések, ha inkább a következő parancsot adja ki a telepítési alkönyvtárban:", + "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Nagyobb telepítések esetén úgy kerülhetők el az időtúllépések, hogy inkább a következő parancsot adja ki a telepítési alkönyvtárban:", "Detailed logs" : "Részletezett naplók", "This %s instance is currently in maintenance mode, which may take a while." : "Ez a %s folyamat éppen karbantartó üzemmódban van, ami eltarthat egy darabig.", - "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a %s példány ismét elérhető." + "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a(z) %s példány ismét elérhető." }, "nplurals=2; plural=(n != 1);"); diff --git a/core/l10n/hu_HU.json b/core/l10n/hu_HU.json index 3111ee2fa72..eebc6f8f97d 100644 --- a/core/l10n/hu_HU.json +++ b/core/l10n/hu_HU.json @@ -1,5 +1,5 @@ { "translations": { - "Please select a file." : "Kérjük, válasszon egy fájlt.", + "Please select a file." : "Kérjük, válasszon ki egy fájlt.", "File is too big" : "A fájl túl nagy", "Invalid file provided" : "Érvénytelen fájl van megadva", "No image or file provided" : "Nincs kép vagy fájl megadva", @@ -96,6 +96,7 @@ "<a href=\"{docUrl}\">There were problems with the code integrity check. More information…</a>" : "<a href=\"{docUrl}\">Problémák vannak a kódintegritás ellenőrzéssel. Bővebb információ…</a>", "Settings" : "Beállítások", "Saving..." : "Mentés...", + "Dismiss" : "Elutasít", "seconds ago" : "pár másodperce", "The link to reset your password has been sent to your email. If you do not receive it within a reasonable amount of time, check your spam/junk folders.<br>If it is not there ask your local administrator." : "A jelszó felülírásához a linket e-mailben elküldtük. Ha a levél elfogadható időn belül nem érkezik meg, ellenőrizze a spam/levélszemét mappát.<br>Ha nincs ott, kérdezze meg a helyi rendszergazdát.", "Your files are encrypted. If you haven't enabled the recovery key, there will be no way to get your data back after your password is reset.<br />If you are not sure what to do, please contact your administrator before you continue. <br />Do you really want to continue?" : "Az Ön állományai titkosítva vannak. Ha nem engedélyezte korábban az adatok visszanyeréséhez szükséges kulcs használatát, akkor a jelszó megváltoztatását követően nem fog hozzáférni az adataihoz. Ha nem biztos abban, hogy mit kellene tennie, akkor kérdezze meg a rendszergazdát, mielőtt továbbmenne.<br />Biztos, hogy folytatni kívánja?", @@ -125,11 +126,19 @@ "Good password" : "Jó jelszó", "Strong password" : "Erős jelszó", "Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken." : "A webszerver nincs megfelelően beállítva a fájl szinkronizációhoz, mert a WebDAV interfész nem működik.", + "Your web server is not set up properly to resolve \"{url}\". Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "A webszerver nincs jól beállítva, hogy kiszolgálja a(z) „{url}” hivatkozást. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", "This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features." : "Ennek a szervernek nincs működő internet kapcsolata. Ez azt jelenti, hogy néhány tulajdonság, mint pl. külső tárolók felcsatolása, frissítési értesítések, vagy egyéb alkalmazások nem működnek. A fájlok távoli elérése és az e-mail értesítések is lehet, hogy nem működnek. Ajánlott az internet kapcsolat engedélyezése a szerveren, ha minden tulajdonságot használni szeretne.", + "No memory cache has been configured. To enhance your performance please configure a memcache if available. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "Nincs memória gyorsítótár beállítva. A teljesítmény növelése érdekében kérjük állítsa be a memcache-t, ha elérhető. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", + "/dev/urandom is not readable by PHP which is highly discouraged for security reasons. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "/dev/urandom nem olvasható a PHP számára, mely nagy biztonsági probléma. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", + "You are currently running PHP {version}. We encourage you to upgrade your PHP version to take advantage of <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">performance and security updates provided by the PHP Group</a> as soon as your distribution supports it." : "Jelenleg {version} PHP verziót használ. Javasoljuk, hogy frissítse a PHP verziót, hogy kihasználhassa a <a target=\"_blank\" rel=\"noreferrer\" href=\"{phpLink}\">teljesítménybeli és a biztonságbeli előnyöket, amiket a PHP csoport kínál</a>, amilyen hamar a disztribúciója támogatja.", + "The reverse proxy headers configuration is incorrect, or you are accessing ownCloud from a trusted proxy. If you are not accessing ownCloud from a trusted proxy, this is a security issue and can allow an attacker to spoof their IP address as visible to ownCloud. Further information can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>." : "A fordított proxy fejlécek konfigurációs beállításai helytelenek, vagy egy megbízható proxy-ból próbálja az ownCloud-ot elérni. Ha nem megbízható proxy-ból próbálja elérni az ownCloud-ot, akkor ez egy biztonsági probléma, a támadó az ownCloud számára látható IP cím csalást tud végrehajtani. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat.", + "Memcached is configured as distributed cache, but the wrong PHP module \"memcache\" is installed. \\OC\\Memcache\\Memcached only supports \"memcached\" and not \"memcache\". See the <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki about both modules</a>." : "Memcached be van konfigurálva gyorsítótárnak, de rossz \"memcache\" PHP modul van telepítve. \\OC\\Memcache\\Memcached csak a \"memcached\"-t támogatja, és nem a \"memcache\"-t. Kérjük, nézze meg a <a target=\"_blank\" rel=\"noreferrer\" href=\"{wikiLink}\">memcached wiki oldalt a modulokkal kapcsolatban</a>.", + "Some files have not passed the integrity check. Further information on how to resolve this issue can be found in our <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">documentation</a>. (<a href=\"{codeIntegrityDownloadEndpoint}\">List of invalid files…</a> / <a href=\"{rescanEndpoint}\">Rescan…</a>)" : "Néhány fájl nem felelt meg az integritás ellenőrzésen. Bővebb információt a <a target=\"_blank\" rel=\"noreferrer\" href=\"{docLink}\">dokumentációban</a> találhat. (<a href=\"{codeIntegrityDownloadEndpoint}\">Érvénytelen fájlok listája…</a> / <a href=\"{rescanEndpoint}\">Újra ellenőrzés…</a>)", "Error occurred while checking server setup" : "Hiba történt a szerver beállítások ellenőrzése közben", "Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root." : "Az adat könyvtára és a fájljai valószínűleg elérhetőek az internetről, mert a .htaccess fájl nem működik. Erősen ajánlott, hogy úgy állítsa be a webszerverét, hogy az adatkönyvtár ne legyen elérhető az internetről, vagy mozgassa ki az adatokat a webszerver gyökérkönyvtárából.", "The \"{header}\" HTTP header is not configured to equal to \"{expected}\". This is a potential security or privacy risk and we recommend adjusting this setting." : "A \"{header}\" HTTP fejléc nincs beállítva, hogy megegyezzen az elvárttal \"{expected}\". Ez egy potenciális biztonsági kockázat és kérjük, hogy változtassa meg a beállításokat.", - "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Jelenleg HTTP-vel éri el a weboldalt. Nagyon ajánlott a HTTPS konfiguráció használata ehelyett, ahogyan ezt részleteztük a <a href=\"{docUrl}\">biztonsági tippek</a> dokumentációban", + "The \"Strict-Transport-Security\" HTTP header is not configured to at least \"{seconds}\" seconds. For enhanced security we recommend enabling HSTS as described in our <a href=\"{docUrl}\" rel=\"noreferrer\">security tips</a>." : "A \"Strict-Transport-Security\" HTTP fejléc nincs beállítva hogy \"{seconds}\" másodpercig tartson. Biztonsági okokból ajánljuk, hogy engedélyezze a HSTS, ahogyan ezt részletezzük a <a href=\"{docUrl}\" rel=\"noreferrer\">biztonsági tippek</a> dokumentációban.", + "You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead as described in our <a href=\"{docUrl}\">security tips</a>." : "Jelenleg HTTP-vel éri el a weboldalt. Erősen ajánlott a HTTPS konfiguráció használata ehelyett, ahogyan ezt részleteztük a <a href=\"{docUrl}\">biztonsági tippek</a> dokumentációban", "Shared" : "Megosztott", "Shared with {recipients}" : "Megosztva ővelük: {recipients}", "Error" : "Hiba", @@ -145,7 +154,7 @@ "Email sent" : "Az e-mailt elküldtük!", "Resharing is not allowed" : "Ezt az állományt csak a tulajdonosa oszthatja meg másokkal", "Share link" : "Megosztás hivatkozással", - "Link" : "Link", + "Link" : "Hivatkozás", "Password protect" : "Jelszóval védett", "Password" : "Jelszó", "Allow editing" : "Szerkesztés engedélyezése", @@ -172,7 +181,7 @@ "{sharee} (at {server})" : "{sharee} ({server} szerveren)", "{sharee} (remote)" : "{sharee} (távoli)", "Share" : "Megosztás", - "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Megosztás más ownCloud szerverekkel, a következő formátum használatával felhasznalo@példa.com/owncloud", + "Share with people on other ownClouds using the syntax username@example.com/owncloud" : "Megosztás más ownCloud szerverekkel, a következő formátum használatával felhasználó@példa.hu/owncloud", "Share with users…" : "Megosztás felhasználókkal", "Share with users, groups or remote users…" : "Megosztás felhasználókkal, csoportokkal vagy távoli felhasználókkal...", "Share with users or groups…" : "Megosztás felhasználókkal vagy csoportokkal...", @@ -186,6 +195,7 @@ "({scope})" : "({scope})", "Delete" : "Törlés", "Rename" : "Átnevezés", + "Collaborative tags" : "Címke hozzárendelése", "The object type is not specified." : "Az objektum típusa nincs megadva.", "Enter new" : "Új beírása", "Add" : "Hozzáadás", @@ -193,7 +203,7 @@ "Error loading dialog template: {error}" : "Hiba a párbeszédpanel-sablon betöltésekor: {error}", "No tags selected for deletion." : "Nincs törlésre kijelölt címke.", "unknown text" : "ismeretlen szöveg", - "Hello world!" : "Üdv, világ!", + "Hello world!" : "Üdv, Világ!", "sunny" : "napos", "Hello {name}, the weather is {weather}" : "Üdv {name}, {weather} időnk van", "Hello {name}" : "Üdv {name}!", @@ -218,7 +228,7 @@ "Access forbidden" : "A hozzáférés nem engedélyezett", "File not found" : "Fájl nem található", "The specified document has not been found on the server." : "A meghatározott dokumentum nem található a szerveren.", - "You can click here to return to %s." : "Ide kattintva visszatérhetsz ide: %s.", + "You can click here to return to %s." : "Ide kattintva visszatérhet ide: %s.", "Hey there,\n\njust letting you know that %s shared %s with you.\nView it: %s\n\n" : "Üdvözöljük!\n\nÉrtesítjük, hogy %s megosztotta Önnel a következőt: %s.\nItt nézheti meg: %s\n\n", "The share will expire on %s." : "A megosztás lejár ekkor: %s.", "Cheers!" : "Üdv.", @@ -237,14 +247,15 @@ "Trace" : "Lekövetés", "Security warning" : "Biztonsági figyelmeztetés", "Your data directory and files are probably accessible from the internet because the .htaccess file does not work." : "Az adatkönyvtár és a benne levő állományok valószínűleg közvetlenül is elérhetők az internetről, mert a .htaccess állomány nem érvényesül.", - "Create an <strong>admin account</strong>" : "<strong>Rendszergazdai belépés</strong> létrehozása", + "For information how to properly configure your server, please see the <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">documentation</a>." : "A kiszolgáló megfelelő beállításához kérjük olvassa el a <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">dokumentációt</a>.", + "Create an <strong>admin account</strong>" : "<strong>Rendszergazdai fiók</strong> létrehozása", "Username" : "Felhasználónév", - "Storage & database" : "Tárolás és adatbázis", + "Storage & database" : "Tárhely és adatbázis", "Data folder" : "Adatkönyvtár", "Configure the database" : "Adatbázis konfigurálása", "Only %s is available." : "Csak %s érhető el.", "Install and activate additional PHP modules to choose other database types." : "Telepítse és aktiválja a bővített PHP modulokat, hogy tudjon más adatbázis típust is kiválasztani.", - "For more details check out the documentation." : "További részletekért kérem ellenőrizze a dokumentációt.", + "For more details check out the documentation." : "További részletekért kérjük ellenőrizze a dokumentációt.", "Database user" : "Adatbázis felhasználónév", "Database password" : "Adatbázis jelszó", "Database name" : "Az adatbázis neve", @@ -259,13 +270,13 @@ "Need help?" : "Segítségre van szüksége?", "See the documentation" : "Nézze meg a dokumentációt", "Hey there,<br><br>just letting you know that %s shared <strong>%s</strong> with you.<br><a href=\"%s\">View it!</a><br><br>" : "Üdvözöljük!<br /><br />\n\nÉrtesítjük, hogy %s megosztotta Önnel a következőt: <strong>%s</strong><br />\n<a href=\"%s\">Itt nézheti meg.</a><br /><br />", - "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Az alkalmazás megfelelő működéséhez JavaScript szükséges. Kérjük {linkstart}engedélyezze a JavaScript-et{linkend} és frissítse a lapot.", - "Log out" : "Kilépés", + "This application requires JavaScript for correct operation. Please {linkstart}enable JavaScript{linkend} and reload the page." : "Az alkalmazás megfelelő működéséhez JavaScript szükséges. Kérjük, {linkstart}engedélyezze a JavaScript-et{linkend} és frissítse a lapot.", + "Log out" : "Kijelentkezés", "Search" : "Keresés", "Server side authentication failed!" : "A szerveroldali hitelesítés sikertelen!", "Please contact your administrator." : "Kérjük, lépjen kapcsolatba a rendszergazdával.", "An internal error occurred." : "Belső hiba történt.", - "Please try again or contact your administrator." : "Kérem próbálja újra, vagy vegye fel a kapcsolatot a rendszergazdával.", + "Please try again or contact your administrator." : "Kérjük, próbálja meg újra, vagy vegye fel a kapcsolatot a rendszergazdával.", "Log in" : "Bejelentkezés", "Wrong password. Reset it?" : "Hibás jelszó. Visszaállítja?", "Wrong password." : "Hibás jelszó.", @@ -282,17 +293,17 @@ "You are accessing the server from an untrusted domain." : "A kiszolgálót nem megbízható domain névvel éri el.", "Please contact your administrator. If you are an administrator of this instance, configure the \"trusted_domains\" setting in config/config.php. An example configuration is provided in config/config.sample.php." : "Kérjük keresse fel a rendszergazdát! Ha ennek a telepítésnek Ön a rendszergazdája, akkor állítsa be a config/config.php állományban a \"trusted_domain\" paramétert! A config/config.sample.php állományban talál példát a beállításra.", "Depending on your configuration, as an administrator you might also be able to use the button below to trust this domain." : "A beállításoktól függően, rendszergazdaként lehetséges, hogy az alábbi gombot is használhatja a domain név megbízhatóvá tételéhez.", - "Add \"%s\" as trusted domain" : "Adjuk hozzá \"%s\"-t a megbízható domain nevekhez!", - "App update required" : "Alkalmazás frissítés szükséges", + "Add \"%s\" as trusted domain" : "Adjuk hozzá „%s”-t a megbízható domain nevekhez!", + "App update required" : "Alkalmazás frissítése szükséges", "%s will be updated to version %s" : "%s frissítve lesz erre a verzióra: %s", "These apps will be updated:" : "A következő alkalmazások lesznek frissítve:", "These incompatible apps will be disabled:" : "A követlező inkompatibilis alkalmazások tiltva lesznek:", - "The theme %s has been disabled." : "Ez a smink: %s letiltásra került.", - "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Kérjük gondoskodjon róla, hogy elmentse az adatbázist, a konfigurációs mappa és az adatamappa tartalmát, mielőtt folytatja.", + "The theme %s has been disabled." : "%s téma letiltásra került.", + "Please make sure that the database, the config folder and the data folder have been backed up before proceeding." : "Kérjük, gondoskodjon róla, hogy elmentse az adatbázist, a konfigurációs mappa és az adatmappa tartalmát, mielőtt folytatja.", "Start update" : "A frissítés megkezdése", - "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Nagyobb telepítések esetén úgy kerülhetők el az időtúllépések, ha inkább a következő parancsot adja ki a telepítési alkönyvtárban:", + "To avoid timeouts with larger installations, you can instead run the following command from your installation directory:" : "Nagyobb telepítések esetén úgy kerülhetők el az időtúllépések, hogy inkább a következő parancsot adja ki a telepítési alkönyvtárban:", "Detailed logs" : "Részletezett naplók", "This %s instance is currently in maintenance mode, which may take a while." : "Ez a %s folyamat éppen karbantartó üzemmódban van, ami eltarthat egy darabig.", - "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a %s példány ismét elérhető." + "This page will refresh itself when the %s instance is available again." : "Ez az oldal frissíteni fogja magát amint a(z) %s példány ismét elérhető." },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/core/routes.php b/core/routes.php index 8981eb618f3..2b7a19f7d86 100644 --- a/core/routes.php +++ b/core/routes.php @@ -42,6 +42,8 @@ $application->registerRoutes($this, [ ['name' => 'avatar#postCroppedAvatar', 'url' => '/avatar/cropped', 'verb' => 'POST'], ['name' => 'avatar#getTmpAvatar', 'url' => '/avatar/tmp', 'verb' => 'GET'], ['name' => 'avatar#postAvatar', 'url' => '/avatar/', 'verb' => 'POST'], + ['name' => 'login#showLoginForm', 'url' => '/login', 'verb' => 'GET'], + ['name' => 'login#logout', 'url' => '/logout', 'verb' => 'GET'], ] ]); diff --git a/core/templates/login.php b/core/templates/login.php index 9934d4988d9..8405bac6890 100644 --- a/core/templates/login.php +++ b/core/templates/login.php @@ -9,7 +9,7 @@ script('core', [ ?> <!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]--> -<form method="post" name="login"> +<form method="post" name="login" action="<?php p(OC::$WEBROOT) ?>/"> <fieldset> <?php if (!empty($_['redirect_url'])) { print_unescaped('<input type="hidden" name="redirect_url" value="' . \OCP\Util::sanitizeHTML($_['redirect_url']) . '">'); @@ -41,7 +41,7 @@ script('core', [ <p class="grouptop"> <input type="text" name="user" id="user" placeholder="<?php p($l->t('Username')); ?>" - value="<?php p($_['username']); ?>" + value="<?php p($_['loginName']); ?>" <?php p($_['user_autofocus'] ? 'autofocus' : ''); ?> autocomplete="on" autocapitalize="off" autocorrect="off" required> <label for="user" class="infield"><?php p($l->t('Username')); ?></label> diff --git a/core/templates/update.use-cli.php b/core/templates/update.use-cli.php new file mode 100644 index 00000000000..52d40cdea55 --- /dev/null +++ b/core/templates/update.use-cli.php @@ -0,0 +1,14 @@ +<div class="update" data-productname="<?php p($_['productName']) ?>" data-version="<?php p($_['version']) ?>"> + <div class="updateOverview"> + <h2 class="title"><?php p($l->t('Update needed')) ?></h2> + <div class="infogroup"> + <?php if ($_['tooBig']) { + p($l->t('Please use the command line updater because you have a big instance.')); + } else { + p($l->t('Please use the command line updater because automatic updating is disabled in the config.php.')); + } ?><br><br> + <?php + print_unescaped($l->t('For help, see the <a target="_blank" rel="noreferrer" href="%s">documentation</a>.', [link_to_docs('admin-cli-upgrade')])); ?><br><br> + </div> + </div> +</div> diff --git a/lib/base.php b/lib/base.php index 79f5c673438..26be1161ba3 100644 --- a/lib/base.php +++ b/lib/base.php @@ -78,19 +78,14 @@ class OC { */ public static $WEBROOT = ''; /** - * The installation path of the 3rdparty folder on the server (e.g. /srv/http/owncloud/3rdparty) - */ - public static $THIRDPARTYROOT = ''; - /** - * the root path of the 3rdparty folder for http requests (e.g. owncloud/3rdparty) - */ - public static $THIRDPARTYWEBROOT = ''; - /** * The installation path array of the apps folder on the server (e.g. /srv/http/owncloud) 'path' and * web path in 'url' */ public static $APPSROOTS = array(); + /** + * @var string + */ public static $configDir; /** @@ -183,25 +178,6 @@ class OC { } } - // search the 3rdparty folder - OC::$THIRDPARTYROOT = self::$config->getValue('3rdpartyroot', null); - OC::$THIRDPARTYWEBROOT = self::$config->getValue('3rdpartyurl', null); - - if (empty(OC::$THIRDPARTYROOT) && empty(OC::$THIRDPARTYWEBROOT)) { - if (file_exists(OC::$SERVERROOT . '/3rdparty')) { - OC::$THIRDPARTYROOT = OC::$SERVERROOT; - OC::$THIRDPARTYWEBROOT = OC::$WEBROOT; - } elseif (file_exists(OC::$SERVERROOT . '/../3rdparty')) { - OC::$THIRDPARTYWEBROOT = rtrim(dirname(OC::$WEBROOT), '/'); - OC::$THIRDPARTYROOT = rtrim(dirname(OC::$SERVERROOT), '/'); - } - } - if (empty(OC::$THIRDPARTYROOT) || !file_exists(OC::$THIRDPARTYROOT)) { - throw new \RuntimeException('3rdparty directory not found! Please put the ownCloud 3rdparty' - . ' folder in the ownCloud folder or the folder above.' - . ' You can also configure the location in the config.php file.'); - } - // search the apps folder $config_paths = self::$config->getValue('apps_paths', array()); if (!empty($config_paths)) { @@ -240,7 +216,7 @@ class OC { set_include_path( OC::$SERVERROOT . '/lib/private' . PATH_SEPARATOR . OC::$SERVERROOT . '/config' . PATH_SEPARATOR . - OC::$THIRDPARTYROOT . '/3rdparty' . PATH_SEPARATOR . + OC::$SERVERROOT . '/3rdparty' . PATH_SEPARATOR . implode(PATH_SEPARATOR, $paths) . PATH_SEPARATOR . get_include_path() . PATH_SEPARATOR . OC::$SERVERROOT @@ -306,7 +282,7 @@ class OC { // render error page $template = new OC_Template('', 'update.user', 'guest'); - OC_Util::addscript('maintenance-check'); + OC_Util::addScript('maintenance-check'); $template->printPage(); die(); } @@ -361,27 +337,49 @@ class OC { */ private static function printUpgradePage() { $systemConfig = \OC::$server->getSystemConfig(); + + $disableWebUpdater = $systemConfig->getValue('upgrade.disable-web', false); + $tooBig = false; + if (!$disableWebUpdater) { + // count users + $stats = \OC::$server->getUserManager()->countUsers(); + $totalUsers = array_sum($stats); + $tooBig = ($totalUsers > 50); + } + if ($disableWebUpdater || $tooBig) { + // send http status 503 + header('HTTP/1.1 503 Service Temporarily Unavailable'); + header('Status: 503 Service Temporarily Unavailable'); + header('Retry-After: 120'); + + // render error page + $template = new OC_Template('', 'update.use-cli', 'guest'); + $template->assign('productName', 'ownCloud'); // for now + $template->assign('version', OC_Util::getVersionString()); + $template->assign('tooBig', $tooBig); + + $template->printPage(); + die(); + } + + // check whether this is a core update or apps update + $installedVersion = $systemConfig->getValue('version', '0.0.0'); + $currentVersion = implode('.', \OCP\Util::getVersion()); + + // if not a core upgrade, then it's apps upgrade + $isAppsOnlyUpgrade = (version_compare($currentVersion, $installedVersion, '=')); + $oldTheme = $systemConfig->getValue('theme'); $systemConfig->setValue('theme', ''); \OCP\Util::addScript('config'); // needed for web root \OCP\Util::addScript('update'); \OCP\Util::addStyle('update'); - // check whether this is a core update or apps update - $installedVersion = $systemConfig->getValue('version', '0.0.0'); - $currentVersion = implode('.', \OCP\Util::getVersion()); - $appManager = \OC::$server->getAppManager(); $tmpl = new OC_Template('', 'update.admin', 'guest'); $tmpl->assign('version', OC_Util::getVersionString()); - - // if not a core upgrade, then it's apps upgrade - if (version_compare($currentVersion, $installedVersion, '=')) { - $tmpl->assign('isAppsOnlyUpgrade', true); - } else { - $tmpl->assign('isAppsOnlyUpgrade', false); - } + $tmpl->assign('isAppsOnlyUpgrade', $isAppsOnlyUpgrade); // get third party apps $ocVersion = \OCP\Util::getVersion(); @@ -447,7 +445,7 @@ class OC { } public static function loadAppClassPaths() { - foreach (OC_APP::getEnabledApps() as $app) { + foreach (OC_App::getEnabledApps() as $app) { $appPath = OC_App::getAppPath($app); if ($appPath === false) { continue; @@ -493,7 +491,7 @@ class OC { try { self::initPaths(); // setup 3rdparty autoloader - $vendorAutoLoad = OC::$THIRDPARTYROOT . '/3rdparty/autoload.php'; + $vendorAutoLoad = OC::$SERVERROOT. '/3rdparty/autoload.php'; if (!file_exists($vendorAutoLoad)) { throw new \RuntimeException('Composer autoloader not found, unable to continue. Check the folder "3rdparty". Running "git submodule update --init" will initialize the git submodule that handles the subfolder "3rdparty".'); } @@ -860,7 +858,7 @@ class OC { } } - if (!self::$CLI and (!isset($_GET["logout"]) or ($_GET["logout"] !== 'true'))) { + if (!self::$CLI) { try { if (!$systemConfig->getValue('maintenance', false) && !self::checkUpgrade(false)) { OC_App::loadApps(array('filesystem', 'logging')); @@ -899,31 +897,13 @@ class OC { return; } - // Redirect to index if the logout link is accessed without valid session - // this is needed to prevent "Token expired" messages while login if a session is expired - // @see https://github.com/owncloud/core/pull/8443#issuecomment-42425583 - if(isset($_GET['logout']) && !OC_User::isLoggedIn()) { - header("Location: " . \OC::$server->getURLGenerator()->getAbsoluteURL('/')); - return; - } - // Someone is logged in if (OC_User::isLoggedIn()) { OC_App::loadApps(); OC_User::setupBackends(); OC_Util::setupFS(); - if (isset($_GET["logout"]) and ($_GET["logout"])) { - OC_JSON::callCheck(); - if (isset($_COOKIE['oc_token'])) { - \OC::$server->getConfig()->deleteUserValue(OC_User::getUser(), 'login_token', $_COOKIE['oc_token']); - } - OC_User::logout(); - // redirect to webroot and add slash if webroot is empty - header("Location: " . \OC::$server->getURLGenerator()->getAbsoluteURL('/')); - } else { - // Redirect to default application - OC_Util::redirectToDefaultPage(); - } + // Redirect to default application + OC_Util::redirectToDefaultPage(); } else { // Not handled and not logged in self::handleLogin(); @@ -975,7 +955,18 @@ class OC { $error[] = 'internalexception'; } - OC_Util::displayLoginPage(array_unique($error), $messages); + if(!\OC::$server->getUserSession()->isLoggedIn()) { + $loginMessages = array(array_unique($error), $messages); + \OC::$server->getSession()->set('loginMessages', $loginMessages); + // Read current user and append if possible + $args = []; + if(isset($_POST['user'])) { + $args['user'] = $_POST['user']; + } + + $redirectionTarget = \OC::$server->getURLGenerator()->linkToRoute('core.login.showLoginForm', $args); + header('Location: ' . $redirectionTarget); + } } /** diff --git a/lib/l10n/cs_CZ.js b/lib/l10n/cs_CZ.js index f2e4916d6b5..f402a168df3 100644 --- a/lib/l10n/cs_CZ.js +++ b/lib/l10n/cs_CZ.js @@ -7,10 +7,6 @@ OC.L10N.register( "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "To lze obvykle vyřešit %spovolením zápisu webovému serveru do konfiguračního adresáře%s.", "Sample configuration detected" : "Byla detekována vzorová konfigurace", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Pravděpodobně byla zkopírována konfigurační nastavení ze vzorových souborů. Toto není podporováno a může poškodit vaši instalaci. Nahlédněte prosím do dokumentace před prováděním změn v souboru config.php", - "You are not allowed to share %s" : "Nemáte povoleno sdílet %s", - "Cannot increase permissions of %s" : "Nelze navýšit oprávnění u %s", - "Expiration date is in the past" : "Datum vypršení je v minulosti", - "Cannot set expiration date more than %s days in the future" : "Datum vypršení nelze nastavit na více než %s dní do budoucnosti", "PHP %s or higher is required." : "Je vyžadováno PHP %s nebo vyšší.", "PHP with a version lower than %s is required." : "Je vyžadováno PHP ve verzi nižší než %s.", "Following databases are supported: %s" : "Jsou podporovány následující databáze: %s", @@ -21,6 +17,10 @@ OC.L10N.register( "Following platforms are supported: %s" : "Jsou podporovány následující systémy: %s", "ownCloud %s or higher is required." : "Je vyžadován ownCloud %s nebo vyšší.", "ownCloud %s or lower is required." : "Je vyžadován ownCloud %s nebo nižší.", + "You are not allowed to share %s" : "Nemáte povoleno sdílet %s", + "Cannot increase permissions of %s" : "Nelze navýšit oprávnění u %s", + "Expiration date is in the past" : "Datum vypršení je v minulosti", + "Cannot set expiration date more than %s days in the future" : "Datum vypršení nelze nastavit na více než %s dní do budoucnosti", "Help" : "Nápověda", "Personal" : "Osobní", "Users" : "Uživatelé", @@ -60,6 +60,7 @@ OC.L10N.register( "Archives of type %s are not supported" : "Archivy typu %s nejsou podporovány", "Failed to open archive when installing app" : "Chyba při otevírání archivu během instalace aplikace", "App does not provide an info.xml file" : "Aplikace neposkytuje soubor info.xml", + "App cannot be installed because appinfo file cannot be read." : "Aplikaci nelze nainstalovat, soubor appinfo nelze číst.", "Signature could not get checked. Please contact the app developer and check your admin screen." : "Podpis nelze ověřit. Kontaktujte prosím vývojáře aplikace a zkontrolujte obrazovku administrace.", "App can't be installed because of not allowed code in the App" : "Aplikace nemůže být nainstalována, protože obsahuje nepovolený kód", "App can't be installed because it is not compatible with this version of ownCloud" : "Aplikace nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud", diff --git a/lib/l10n/cs_CZ.json b/lib/l10n/cs_CZ.json index acc708383f9..4ae661477c2 100644 --- a/lib/l10n/cs_CZ.json +++ b/lib/l10n/cs_CZ.json @@ -5,10 +5,6 @@ "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "To lze obvykle vyřešit %spovolením zápisu webovému serveru do konfiguračního adresáře%s.", "Sample configuration detected" : "Byla detekována vzorová konfigurace", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Pravděpodobně byla zkopírována konfigurační nastavení ze vzorových souborů. Toto není podporováno a může poškodit vaši instalaci. Nahlédněte prosím do dokumentace před prováděním změn v souboru config.php", - "You are not allowed to share %s" : "Nemáte povoleno sdílet %s", - "Cannot increase permissions of %s" : "Nelze navýšit oprávnění u %s", - "Expiration date is in the past" : "Datum vypršení je v minulosti", - "Cannot set expiration date more than %s days in the future" : "Datum vypršení nelze nastavit na více než %s dní do budoucnosti", "PHP %s or higher is required." : "Je vyžadováno PHP %s nebo vyšší.", "PHP with a version lower than %s is required." : "Je vyžadováno PHP ve verzi nižší než %s.", "Following databases are supported: %s" : "Jsou podporovány následující databáze: %s", @@ -19,6 +15,10 @@ "Following platforms are supported: %s" : "Jsou podporovány následující systémy: %s", "ownCloud %s or higher is required." : "Je vyžadován ownCloud %s nebo vyšší.", "ownCloud %s or lower is required." : "Je vyžadován ownCloud %s nebo nižší.", + "You are not allowed to share %s" : "Nemáte povoleno sdílet %s", + "Cannot increase permissions of %s" : "Nelze navýšit oprávnění u %s", + "Expiration date is in the past" : "Datum vypršení je v minulosti", + "Cannot set expiration date more than %s days in the future" : "Datum vypršení nelze nastavit na více než %s dní do budoucnosti", "Help" : "Nápověda", "Personal" : "Osobní", "Users" : "Uživatelé", @@ -58,6 +58,7 @@ "Archives of type %s are not supported" : "Archivy typu %s nejsou podporovány", "Failed to open archive when installing app" : "Chyba při otevírání archivu během instalace aplikace", "App does not provide an info.xml file" : "Aplikace neposkytuje soubor info.xml", + "App cannot be installed because appinfo file cannot be read." : "Aplikaci nelze nainstalovat, soubor appinfo nelze číst.", "Signature could not get checked. Please contact the app developer and check your admin screen." : "Podpis nelze ověřit. Kontaktujte prosím vývojáře aplikace a zkontrolujte obrazovku administrace.", "App can't be installed because of not allowed code in the App" : "Aplikace nemůže být nainstalována, protože obsahuje nepovolený kód", "App can't be installed because it is not compatible with this version of ownCloud" : "Aplikace nemůže být nainstalována, protože není kompatibilní s touto verzí ownCloud", diff --git a/lib/l10n/es.js b/lib/l10n/es.js index b2b04e15f3c..dfb9f4cff2e 100644 --- a/lib/l10n/es.js +++ b/lib/l10n/es.js @@ -7,10 +7,6 @@ OC.L10N.register( "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "Esto puede solucionarse fácilmente %sotorgándole permisos de escritura al directorio de configuración%s.", "Sample configuration detected" : "Ejemplo de configuración detectado", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Se ha detectado que el ejemplo de configuración ha sido copiado. Esto puede arruinar su instalación y es un caso para el que no se brinda soporte. Lea la documentación antes de hacer cambios en config.php", - "You are not allowed to share %s" : "Usted no está autorizado para compartir %s", - "Cannot increase permissions of %s" : "No se pueden incrementar los permisos de %s", - "Expiration date is in the past" : "Ha pasado la fecha de caducidad", - "Cannot set expiration date more than %s days in the future" : "No se puede fijar la fecha de caducidad más de %s días en el futuro.", "PHP %s or higher is required." : "Se requiere PHP %s o superior.", "PHP with a version lower than %s is required." : "PHP con una versión inferior que %s la requerida.", "Following databases are supported: %s" : "Las siguientes bases de datos están soportadas: %s", @@ -21,11 +17,16 @@ OC.L10N.register( "Following platforms are supported: %s" : "Las siguientes plataformas están soportadas: %s", "ownCloud %s or higher is required." : "Se requiere ownCloud %s o superior.", "ownCloud %s or lower is required." : "Se requiere ownCloud %s o una versión inferior.", + "You are not allowed to share %s" : "Usted no está autorizado para compartir %s", + "Cannot increase permissions of %s" : "No se pueden incrementar los permisos de %s", + "Expiration date is in the past" : "Ha pasado la fecha de caducidad", + "Cannot set expiration date more than %s days in the future" : "No se puede fijar la fecha de caducidad más de %s días en el futuro.", "Help" : "Ayuda", "Personal" : "Personal", "Users" : "Usuarios", "Admin" : "Administración", "Recommended" : "Recomendado", + "App \"%s\" cannot be installed because appinfo file cannot be read." : "La app \"%s\" no puede ser instalada debido a que no se puede leer la información de la app.", "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "La App \"%s\" no puede ser instalada porque no es compatible con esta versión de ownCloud.", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "La app \"%s\" no puede instalarse porque las siguientes dependencias no están cumplimentadas: %s", "No app name specified" : "No se ha especificado nombre de la aplicación", @@ -60,6 +61,7 @@ OC.L10N.register( "Archives of type %s are not supported" : "Los ficheros de tipo %s no son soportados", "Failed to open archive when installing app" : "Falló la apertura ded fichero mientras se instalaba la aplicación", "App does not provide an info.xml file" : "La aplicación no suministra un fichero info.xml", + "App cannot be installed because appinfo file cannot be read." : "La app no puede ser instalada debido a que no se puede leer la información de la app.", "Signature could not get checked. Please contact the app developer and check your admin screen." : "La firma no pudo ser evaluada. Por favor, contacte con el desarrollador de la aplicación y compruebe su pantalla de administración.", "App can't be installed because of not allowed code in the App" : "La aplicación no puede ser instalada por tener código no autorizado en la aplicación", "App can't be installed because it is not compatible with this version of ownCloud" : "La aplicación no se puede instalar porque no es compatible con esta versión de ownCloud", @@ -69,6 +71,7 @@ OC.L10N.register( "Authentication error" : "Error de autenticación", "Token expired. Please reload page." : "Token expirado. Por favor, recarge la página.", "Unknown user" : "Usuario desconocido", + "%s enter the database username and name." : "%s introduzca el nombre de usuario y la contraseña de la BBDD.", "%s enter the database username." : "%s ingresar el usuario de la base de datos.", "%s enter the database name." : "%s ingresar el nombre de la base de datos", "%s you may not use dots in the database name" : "%s puede utilizar puntos en el nombre de la base de datos", diff --git a/lib/l10n/es.json b/lib/l10n/es.json index db87962de70..0b8cfd04344 100644 --- a/lib/l10n/es.json +++ b/lib/l10n/es.json @@ -5,10 +5,6 @@ "This can usually be fixed by %sgiving the webserver write access to the config directory%s." : "Esto puede solucionarse fácilmente %sotorgándole permisos de escritura al directorio de configuración%s.", "Sample configuration detected" : "Ejemplo de configuración detectado", "It has been detected that the sample configuration has been copied. This can break your installation and is unsupported. Please read the documentation before performing changes on config.php" : "Se ha detectado que el ejemplo de configuración ha sido copiado. Esto puede arruinar su instalación y es un caso para el que no se brinda soporte. Lea la documentación antes de hacer cambios en config.php", - "You are not allowed to share %s" : "Usted no está autorizado para compartir %s", - "Cannot increase permissions of %s" : "No se pueden incrementar los permisos de %s", - "Expiration date is in the past" : "Ha pasado la fecha de caducidad", - "Cannot set expiration date more than %s days in the future" : "No se puede fijar la fecha de caducidad más de %s días en el futuro.", "PHP %s or higher is required." : "Se requiere PHP %s o superior.", "PHP with a version lower than %s is required." : "PHP con una versión inferior que %s la requerida.", "Following databases are supported: %s" : "Las siguientes bases de datos están soportadas: %s", @@ -19,11 +15,16 @@ "Following platforms are supported: %s" : "Las siguientes plataformas están soportadas: %s", "ownCloud %s or higher is required." : "Se requiere ownCloud %s o superior.", "ownCloud %s or lower is required." : "Se requiere ownCloud %s o una versión inferior.", + "You are not allowed to share %s" : "Usted no está autorizado para compartir %s", + "Cannot increase permissions of %s" : "No se pueden incrementar los permisos de %s", + "Expiration date is in the past" : "Ha pasado la fecha de caducidad", + "Cannot set expiration date more than %s days in the future" : "No se puede fijar la fecha de caducidad más de %s días en el futuro.", "Help" : "Ayuda", "Personal" : "Personal", "Users" : "Usuarios", "Admin" : "Administración", "Recommended" : "Recomendado", + "App \"%s\" cannot be installed because appinfo file cannot be read." : "La app \"%s\" no puede ser instalada debido a que no se puede leer la información de la app.", "App \"%s\" cannot be installed because it is not compatible with this version of ownCloud." : "La App \"%s\" no puede ser instalada porque no es compatible con esta versión de ownCloud.", "App \"%s\" cannot be installed because the following dependencies are not fulfilled: %s" : "La app \"%s\" no puede instalarse porque las siguientes dependencias no están cumplimentadas: %s", "No app name specified" : "No se ha especificado nombre de la aplicación", @@ -58,6 +59,7 @@ "Archives of type %s are not supported" : "Los ficheros de tipo %s no son soportados", "Failed to open archive when installing app" : "Falló la apertura ded fichero mientras se instalaba la aplicación", "App does not provide an info.xml file" : "La aplicación no suministra un fichero info.xml", + "App cannot be installed because appinfo file cannot be read." : "La app no puede ser instalada debido a que no se puede leer la información de la app.", "Signature could not get checked. Please contact the app developer and check your admin screen." : "La firma no pudo ser evaluada. Por favor, contacte con el desarrollador de la aplicación y compruebe su pantalla de administración.", "App can't be installed because of not allowed code in the App" : "La aplicación no puede ser instalada por tener código no autorizado en la aplicación", "App can't be installed because it is not compatible with this version of ownCloud" : "La aplicación no se puede instalar porque no es compatible con esta versión de ownCloud", @@ -67,6 +69,7 @@ "Authentication error" : "Error de autenticación", "Token expired. Please reload page." : "Token expirado. Por favor, recarge la página.", "Unknown user" : "Usuario desconocido", + "%s enter the database username and name." : "%s introduzca el nombre de usuario y la contraseña de la BBDD.", "%s enter the database username." : "%s ingresar el usuario de la base de datos.", "%s enter the database name." : "%s ingresar el nombre de la base de datos", "%s you may not use dots in the database name" : "%s puede utilizar puntos en el nombre de la base de datos", diff --git a/lib/private/app/appmanager.php b/lib/private/App/AppManager.php index 69e5334774e..69e5334774e 100644 --- a/lib/private/app/appmanager.php +++ b/lib/private/App/AppManager.php diff --git a/lib/private/app/codechecker/abstractcheck.php b/lib/private/App/CodeChecker/AbstractCheck.php index ca91d366482..ca91d366482 100644 --- a/lib/private/app/codechecker/abstractcheck.php +++ b/lib/private/App/CodeChecker/AbstractCheck.php diff --git a/lib/private/app/codechecker/codechecker.php b/lib/private/App/CodeChecker/CodeChecker.php index 0ca597ccb4e..0ca597ccb4e 100644 --- a/lib/private/app/codechecker/codechecker.php +++ b/lib/private/App/CodeChecker/CodeChecker.php diff --git a/lib/private/app/codechecker/deprecationcheck.php b/lib/private/App/CodeChecker/DeprecationCheck.php index fa5eae8ab1d..fa5eae8ab1d 100644 --- a/lib/private/app/codechecker/deprecationcheck.php +++ b/lib/private/App/CodeChecker/DeprecationCheck.php diff --git a/lib/private/app/codechecker/emptycheck.php b/lib/private/App/CodeChecker/EmptyCheck.php index b779926d5e4..b779926d5e4 100644 --- a/lib/private/app/codechecker/emptycheck.php +++ b/lib/private/App/CodeChecker/EmptyCheck.php diff --git a/lib/private/app/codechecker/icheck.php b/lib/private/App/CodeChecker/ICheck.php index 97e0bc9b8a0..97e0bc9b8a0 100644 --- a/lib/private/app/codechecker/icheck.php +++ b/lib/private/App/CodeChecker/ICheck.php diff --git a/lib/private/app/codechecker/infochecker.php b/lib/private/App/CodeChecker/InfoChecker.php index 812007d8839..812007d8839 100644 --- a/lib/private/app/codechecker/infochecker.php +++ b/lib/private/App/CodeChecker/InfoChecker.php diff --git a/lib/private/app/codechecker/nodevisitor.php b/lib/private/App/CodeChecker/NodeVisitor.php index f9386caeeae..f9386caeeae 100644 --- a/lib/private/app/codechecker/nodevisitor.php +++ b/lib/private/App/CodeChecker/NodeVisitor.php diff --git a/lib/private/app/codechecker/privatecheck.php b/lib/private/App/CodeChecker/PrivateCheck.php index 32248ab21e2..32248ab21e2 100644 --- a/lib/private/app/codechecker/privatecheck.php +++ b/lib/private/App/CodeChecker/PrivateCheck.php diff --git a/lib/private/app/codechecker/strongcomparisoncheck.php b/lib/private/App/CodeChecker/StrongComparisonCheck.php index 919647a6a54..919647a6a54 100644 --- a/lib/private/app/codechecker/strongcomparisoncheck.php +++ b/lib/private/App/CodeChecker/StrongComparisonCheck.php diff --git a/lib/private/app/dependencyanalyzer.php b/lib/private/App/DependencyAnalyzer.php index 6519e15bd8b..6519e15bd8b 100644 --- a/lib/private/app/dependencyanalyzer.php +++ b/lib/private/App/DependencyAnalyzer.php diff --git a/lib/private/app/infoparser.php b/lib/private/App/InfoParser.php index c33e5349f3b..c33e5349f3b 100644 --- a/lib/private/app/infoparser.php +++ b/lib/private/App/InfoParser.php diff --git a/lib/private/app/platform.php b/lib/private/App/Platform.php index 1d4c3767121..1d4c3767121 100644 --- a/lib/private/app/platform.php +++ b/lib/private/App/Platform.php diff --git a/lib/private/app/platformrepository.php b/lib/private/App/PlatformRepository.php index 7363b2a44b1..7363b2a44b1 100644 --- a/lib/private/app/platformrepository.php +++ b/lib/private/App/PlatformRepository.php diff --git a/lib/private/cache/cappedmemorycache.php b/lib/private/Cache/CappedMemoryCache.php index e3efbf76a23..e3efbf76a23 100644 --- a/lib/private/cache/cappedmemorycache.php +++ b/lib/private/Cache/CappedMemoryCache.php diff --git a/lib/private/cache/file.php b/lib/private/Cache/File.php index 989e05275b7..989e05275b7 100644 --- a/lib/private/cache/file.php +++ b/lib/private/Cache/File.php diff --git a/lib/private/command/asyncbus.php b/lib/private/Command/AsyncBus.php index eb692f9a8fb..eb692f9a8fb 100644 --- a/lib/private/command/asyncbus.php +++ b/lib/private/Command/AsyncBus.php diff --git a/lib/private/command/callablejob.php b/lib/private/Command/CallableJob.php index acfeb83d606..acfeb83d606 100644 --- a/lib/private/command/callablejob.php +++ b/lib/private/Command/CallableJob.php diff --git a/lib/private/command/closurejob.php b/lib/private/Command/ClosureJob.php index be2b5f0a4ba..be2b5f0a4ba 100644 --- a/lib/private/command/closurejob.php +++ b/lib/private/Command/ClosureJob.php diff --git a/lib/private/command/commandjob.php b/lib/private/Command/CommandJob.php index 5d613c0305b..5d613c0305b 100644 --- a/lib/private/command/commandjob.php +++ b/lib/private/Command/CommandJob.php diff --git a/lib/private/command/fileaccess.php b/lib/private/Command/FileAccess.php index 6fe3e111aef..6fe3e111aef 100644 --- a/lib/private/command/fileaccess.php +++ b/lib/private/Command/FileAccess.php diff --git a/lib/private/command/queuebus.php b/lib/private/Command/QueueBus.php index be4ee589e6f..be4ee589e6f 100644 --- a/lib/private/command/queuebus.php +++ b/lib/private/Command/QueueBus.php diff --git a/lib/private/comments/comment.php b/lib/private/Comments/Comment.php index 60663d61578..60663d61578 100644 --- a/lib/private/comments/comment.php +++ b/lib/private/Comments/Comment.php diff --git a/lib/private/comments/manager.php b/lib/private/Comments/Manager.php index b986c8c51f9..b986c8c51f9 100644 --- a/lib/private/comments/manager.php +++ b/lib/private/Comments/Manager.php diff --git a/lib/private/comments/managerfactory.php b/lib/private/Comments/ManagerFactory.php index 044463d1e96..044463d1e96 100644 --- a/lib/private/comments/managerfactory.php +++ b/lib/private/Comments/ManagerFactory.php diff --git a/lib/private/db/adapter.php b/lib/private/DB/Adapter.php index 9522f768c88..9522f768c88 100644 --- a/lib/private/db/adapter.php +++ b/lib/private/DB/Adapter.php diff --git a/lib/private/db/adaptermysql.php b/lib/private/DB/AdapterMySQL.php index ab87c589747..ab87c589747 100644 --- a/lib/private/db/adaptermysql.php +++ b/lib/private/DB/AdapterMySQL.php diff --git a/lib/private/db/adapteroci8.php b/lib/private/DB/AdapterOCI8.php index 970d3eefa4d..970d3eefa4d 100644 --- a/lib/private/db/adapteroci8.php +++ b/lib/private/DB/AdapterOCI8.php diff --git a/lib/private/db/adapterpgsql.php b/lib/private/DB/AdapterPgSql.php index a7d9377a0bf..a7d9377a0bf 100644 --- a/lib/private/db/adapterpgsql.php +++ b/lib/private/DB/AdapterPgSql.php diff --git a/lib/private/db/adaptersqlite.php b/lib/private/DB/AdapterSqlite.php index d7769238abc..d7769238abc 100644 --- a/lib/private/db/adaptersqlite.php +++ b/lib/private/DB/AdapterSqlite.php diff --git a/lib/private/db/connection.php b/lib/private/DB/Connection.php index 7904fab0726..7904fab0726 100644 --- a/lib/private/db/connection.php +++ b/lib/private/DB/Connection.php diff --git a/lib/private/db/connectionfactory.php b/lib/private/DB/ConnectionFactory.php index 0856d8d19c0..0856d8d19c0 100644 --- a/lib/private/db/connectionfactory.php +++ b/lib/private/DB/ConnectionFactory.php diff --git a/lib/private/db/mdb2schemamanager.php b/lib/private/DB/MDB2SchemaManager.php index f73f6b4351a..f73f6b4351a 100644 --- a/lib/private/db/mdb2schemamanager.php +++ b/lib/private/DB/MDB2SchemaManager.php diff --git a/lib/private/db/mdb2schemareader.php b/lib/private/DB/MDB2SchemaReader.php index 375fec185cb..375fec185cb 100644 --- a/lib/private/db/mdb2schemareader.php +++ b/lib/private/DB/MDB2SchemaReader.php diff --git a/lib/private/db/mdb2schemawriter.php b/lib/private/DB/MDB2SchemaWriter.php index 7dc3bd223a7..7dc3bd223a7 100644 --- a/lib/private/db/mdb2schemawriter.php +++ b/lib/private/DB/MDB2SchemaWriter.php diff --git a/lib/private/db/migrationexception.php b/lib/private/DB/MigrationException.php index 57e4c5b8334..57e4c5b8334 100644 --- a/lib/private/db/migrationexception.php +++ b/lib/private/DB/MigrationException.php diff --git a/lib/private/db/migrator.php b/lib/private/DB/Migrator.php index 8b8a34d9865..8b8a34d9865 100644 --- a/lib/private/db/migrator.php +++ b/lib/private/DB/Migrator.php diff --git a/lib/private/db/mysqlmigrator.php b/lib/private/DB/MySQLMigrator.php index 1b3f70a817d..1b3f70a817d 100644 --- a/lib/private/db/mysqlmigrator.php +++ b/lib/private/DB/MySQLMigrator.php diff --git a/lib/private/db/nocheckmigrator.php b/lib/private/DB/NoCheckMigrator.php index 23afae11816..23afae11816 100644 --- a/lib/private/db/nocheckmigrator.php +++ b/lib/private/DB/NoCheckMigrator.php diff --git a/lib/private/db/ocsqliteplatform.php b/lib/private/DB/OCSqlitePlatform.php index fe68bc3cc91..fe68bc3cc91 100644 --- a/lib/private/db/ocsqliteplatform.php +++ b/lib/private/DB/OCSqlitePlatform.php diff --git a/lib/private/db/oracleconnection.php b/lib/private/DB/OracleConnection.php index a95f37a8e6c..a95f37a8e6c 100644 --- a/lib/private/db/oracleconnection.php +++ b/lib/private/DB/OracleConnection.php diff --git a/lib/private/db/oraclemigrator.php b/lib/private/DB/OracleMigrator.php index ceb89cf64d4..ceb89cf64d4 100644 --- a/lib/private/db/oraclemigrator.php +++ b/lib/private/DB/OracleMigrator.php diff --git a/lib/private/db/pgsqltools.php b/lib/private/DB/PgSqlTools.php index e9e507551e6..e9e507551e6 100644 --- a/lib/private/db/pgsqltools.php +++ b/lib/private/DB/PgSqlTools.php diff --git a/lib/private/db/querybuilder/compositeexpression.php b/lib/private/DB/QueryBuilder/CompositeExpression.php index 927dfe38378..927dfe38378 100644 --- a/lib/private/db/querybuilder/compositeexpression.php +++ b/lib/private/DB/QueryBuilder/CompositeExpression.php diff --git a/lib/private/db/querybuilder/expressionbuilder/expressionbuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php index ce98816c42d..ce98816c42d 100644 --- a/lib/private/db/querybuilder/expressionbuilder/expressionbuilder.php +++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/ExpressionBuilder.php diff --git a/lib/private/db/querybuilder/expressionbuilder/mysqlexpressionbuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php index 0d34787d26a..0d34787d26a 100644 --- a/lib/private/db/querybuilder/expressionbuilder/mysqlexpressionbuilder.php +++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/MySqlExpressionBuilder.php diff --git a/lib/private/db/querybuilder/expressionbuilder/ociexpressionbuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/OCIExpressionBuilder.php index 5d615ae52e8..5d615ae52e8 100644 --- a/lib/private/db/querybuilder/expressionbuilder/ociexpressionbuilder.php +++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/OCIExpressionBuilder.php diff --git a/lib/private/db/querybuilder/expressionbuilder/pgsqlexpressionbuilder.php b/lib/private/DB/QueryBuilder/ExpressionBuilder/PgSqlExpressionBuilder.php index a8f1af87a45..a8f1af87a45 100644 --- a/lib/private/db/querybuilder/expressionbuilder/pgsqlexpressionbuilder.php +++ b/lib/private/DB/QueryBuilder/ExpressionBuilder/PgSqlExpressionBuilder.php diff --git a/lib/private/db/querybuilder/literal.php b/lib/private/DB/QueryBuilder/Literal.php index 0cc96ab48b4..0cc96ab48b4 100644 --- a/lib/private/db/querybuilder/literal.php +++ b/lib/private/DB/QueryBuilder/Literal.php diff --git a/lib/private/db/querybuilder/parameter.php b/lib/private/DB/QueryBuilder/Parameter.php index 1c233c83f1d..1c233c83f1d 100644 --- a/lib/private/db/querybuilder/parameter.php +++ b/lib/private/DB/QueryBuilder/Parameter.php diff --git a/lib/private/db/querybuilder/querybuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php index bb463e43a75..bb463e43a75 100644 --- a/lib/private/db/querybuilder/querybuilder.php +++ b/lib/private/DB/QueryBuilder/QueryBuilder.php diff --git a/lib/private/db/querybuilder/queryfunction.php b/lib/private/DB/QueryBuilder/QueryFunction.php index ac6d73f3cbf..ac6d73f3cbf 100644 --- a/lib/private/db/querybuilder/queryfunction.php +++ b/lib/private/DB/QueryBuilder/QueryFunction.php diff --git a/lib/private/db/querybuilder/quotehelper.php b/lib/private/DB/QueryBuilder/QuoteHelper.php index fda243a3786..fda243a3786 100644 --- a/lib/private/db/querybuilder/quotehelper.php +++ b/lib/private/DB/QueryBuilder/QuoteHelper.php diff --git a/lib/private/db/sqlitemigrator.php b/lib/private/DB/SQLiteMigrator.php index 8ea32581011..8ea32581011 100644 --- a/lib/private/db/sqlitemigrator.php +++ b/lib/private/DB/SQLiteMigrator.php diff --git a/lib/private/db/sqlitesessioninit.php b/lib/private/DB/SQLiteSessionInit.php index 0683c47d08e..0683c47d08e 100644 --- a/lib/private/db/sqlitesessioninit.php +++ b/lib/private/DB/SQLiteSessionInit.php diff --git a/lib/private/lock/abstractlockingprovider.php b/lib/private/Lock/AbstractLockingProvider.php index f96358778c1..f96358778c1 100644 --- a/lib/private/lock/abstractlockingprovider.php +++ b/lib/private/Lock/AbstractLockingProvider.php diff --git a/lib/private/lock/dblockingprovider.php b/lib/private/Lock/DBLockingProvider.php index 9e97df44d3f..9e97df44d3f 100644 --- a/lib/private/lock/dblockingprovider.php +++ b/lib/private/Lock/DBLockingProvider.php diff --git a/lib/private/lock/memcachelockingprovider.php b/lib/private/Lock/MemcacheLockingProvider.php index 536b29e2c28..536b29e2c28 100644 --- a/lib/private/lock/memcachelockingprovider.php +++ b/lib/private/Lock/MemcacheLockingProvider.php diff --git a/lib/private/lock/nooplockingprovider.php b/lib/private/Lock/NoopLockingProvider.php index dc58230f77e..dc58230f77e 100644 --- a/lib/private/lock/nooplockingprovider.php +++ b/lib/private/Lock/NoopLockingProvider.php diff --git a/lib/private/memcache/apc.php b/lib/private/Memcache/APC.php index 2354ad07749..2354ad07749 100644 --- a/lib/private/memcache/apc.php +++ b/lib/private/Memcache/APC.php diff --git a/lib/private/memcache/apcu.php b/lib/private/Memcache/APCu.php index 350ce913ed8..350ce913ed8 100644 --- a/lib/private/memcache/apcu.php +++ b/lib/private/Memcache/APCu.php diff --git a/lib/private/memcache/arraycache.php b/lib/private/Memcache/ArrayCache.php index 837f888a307..837f888a307 100644 --- a/lib/private/memcache/arraycache.php +++ b/lib/private/Memcache/ArrayCache.php diff --git a/lib/private/memcache/cadtrait.php b/lib/private/Memcache/CADTrait.php index d44d98cba0b..d44d98cba0b 100644 --- a/lib/private/memcache/cadtrait.php +++ b/lib/private/Memcache/CADTrait.php diff --git a/lib/private/memcache/castrait.php b/lib/private/Memcache/CASTrait.php index 43253fc966b..43253fc966b 100644 --- a/lib/private/memcache/castrait.php +++ b/lib/private/Memcache/CASTrait.php diff --git a/lib/private/memcache/cache.php b/lib/private/Memcache/Cache.php index 63d20721aac..63d20721aac 100644 --- a/lib/private/memcache/cache.php +++ b/lib/private/Memcache/Cache.php diff --git a/lib/private/memcache/factory.php b/lib/private/Memcache/Factory.php index a005f319b3e..a005f319b3e 100644 --- a/lib/private/memcache/factory.php +++ b/lib/private/Memcache/Factory.php diff --git a/lib/private/memcache/memcached.php b/lib/private/Memcache/Memcached.php index a30f9da7ed7..a30f9da7ed7 100644 --- a/lib/private/memcache/memcached.php +++ b/lib/private/Memcache/Memcached.php diff --git a/lib/private/memcache/nullcache.php b/lib/private/Memcache/NullCache.php index c490ca7e03c..c490ca7e03c 100644 --- a/lib/private/memcache/nullcache.php +++ b/lib/private/Memcache/NullCache.php diff --git a/lib/private/memcache/redis.php b/lib/private/Memcache/Redis.php index b3444a2b4e9..b3444a2b4e9 100644 --- a/lib/private/memcache/redis.php +++ b/lib/private/Memcache/Redis.php diff --git a/lib/private/memcache/xcache.php b/lib/private/Memcache/XCache.php index e80901faadc..e80901faadc 100644 --- a/lib/private/memcache/xcache.php +++ b/lib/private/Memcache/XCache.php diff --git a/lib/private/notification/action.php b/lib/private/Notification/Action.php index deac6807653..deac6807653 100644 --- a/lib/private/notification/action.php +++ b/lib/private/Notification/Action.php diff --git a/lib/private/notification/manager.php b/lib/private/Notification/Manager.php index 3ddc9b21161..3ddc9b21161 100644 --- a/lib/private/notification/manager.php +++ b/lib/private/Notification/Manager.php diff --git a/lib/private/notification/notification.php b/lib/private/Notification/Notification.php index db0a76a7c32..db0a76a7c32 100644 --- a/lib/private/notification/notification.php +++ b/lib/private/Notification/Notification.php diff --git a/lib/private/security/csp/contentsecuritypolicy.php b/lib/private/Security/CSP/ContentSecurityPolicy.php index 25eacfab1d6..25eacfab1d6 100644 --- a/lib/private/security/csp/contentsecuritypolicy.php +++ b/lib/private/Security/CSP/ContentSecurityPolicy.php diff --git a/lib/private/security/csp/contentsecuritypolicymanager.php b/lib/private/Security/CSP/ContentSecurityPolicyManager.php index 760cd36e56b..760cd36e56b 100644 --- a/lib/private/security/csp/contentsecuritypolicymanager.php +++ b/lib/private/Security/CSP/ContentSecurityPolicyManager.php diff --git a/lib/private/security/csrf/csrftoken.php b/lib/private/Security/CSRF/CsrfToken.php index 4524d0db6e6..4524d0db6e6 100644 --- a/lib/private/security/csrf/csrftoken.php +++ b/lib/private/Security/CSRF/CsrfToken.php diff --git a/lib/private/security/csrf/csrftokengenerator.php b/lib/private/Security/CSRF/CsrfTokenGenerator.php index 6ea71636d22..6ea71636d22 100644 --- a/lib/private/security/csrf/csrftokengenerator.php +++ b/lib/private/Security/CSRF/CsrfTokenGenerator.php diff --git a/lib/private/security/csrf/csrftokenmanager.php b/lib/private/Security/CSRF/CsrfTokenManager.php index 8d1bf5c0819..8d1bf5c0819 100644 --- a/lib/private/security/csrf/csrftokenmanager.php +++ b/lib/private/Security/CSRF/CsrfTokenManager.php diff --git a/lib/private/security/csrf/tokenstorage/sessionstorage.php b/lib/private/Security/CSRF/TokenStorage/SessionStorage.php index e1c8c96e920..e1c8c96e920 100644 --- a/lib/private/security/csrf/tokenstorage/sessionstorage.php +++ b/lib/private/Security/CSRF/TokenStorage/SessionStorage.php diff --git a/lib/private/security/certificate.php b/lib/private/Security/Certificate.php index 54486ff51fe..54486ff51fe 100644 --- a/lib/private/security/certificate.php +++ b/lib/private/Security/Certificate.php diff --git a/lib/private/security/certificatemanager.php b/lib/private/Security/CertificateManager.php index f4932ca568e..f4932ca568e 100644 --- a/lib/private/security/certificatemanager.php +++ b/lib/private/Security/CertificateManager.php diff --git a/lib/private/security/credentialsmanager.php b/lib/private/Security/CredentialsManager.php index d4104dbe712..d4104dbe712 100644 --- a/lib/private/security/credentialsmanager.php +++ b/lib/private/Security/CredentialsManager.php diff --git a/lib/private/security/crypto.php b/lib/private/Security/Crypto.php index 3c3ffb47398..3c3ffb47398 100644 --- a/lib/private/security/crypto.php +++ b/lib/private/Security/Crypto.php diff --git a/lib/private/security/hasher.php b/lib/private/Security/Hasher.php index a8b81aa60eb..a8b81aa60eb 100644 --- a/lib/private/security/hasher.php +++ b/lib/private/Security/Hasher.php diff --git a/lib/private/security/securerandom.php b/lib/private/Security/SecureRandom.php index 45cb3f17ee4..45cb3f17ee4 100644 --- a/lib/private/security/securerandom.php +++ b/lib/private/Security/SecureRandom.php diff --git a/lib/private/security/trusteddomainhelper.php b/lib/private/Security/TrustedDomainHelper.php index 409628677a7..409628677a7 100644 --- a/lib/private/security/trusteddomainhelper.php +++ b/lib/private/Security/TrustedDomainHelper.php diff --git a/lib/private/Server.php b/lib/private/Server.php index b29f4f9000c..d37edc4f45f 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -74,6 +74,7 @@ use OC\Security\SecureRandom; use OC\Security\TrustedDomainHelper; use OC\Session\CryptoWrapper; use OC\Tagging\TagMapper; +use OCP\IL10N; use OCP\IServerContainer; use OCP\Security\IContentSecurityPolicyManager; use Symfony\Component\EventDispatcher\EventDispatcher; @@ -857,7 +858,7 @@ class Server extends ServerContainer implements IServerContainer { * * @param string $app appid * @param string $lang - * @return \OC_L10N + * @return IL10N */ public function getL10N($app, $lang = null) { return $this->getL10NFactory()->get($app, $lang); diff --git a/lib/private/session/cryptosessiondata.php b/lib/private/Session/CryptoSessionData.php index f6c585c1611..f6c585c1611 100644 --- a/lib/private/session/cryptosessiondata.php +++ b/lib/private/Session/CryptoSessionData.php diff --git a/lib/private/session/cryptowrapper.php b/lib/private/Session/CryptoWrapper.php index f1819b31b89..f1819b31b89 100644 --- a/lib/private/session/cryptowrapper.php +++ b/lib/private/Session/CryptoWrapper.php diff --git a/lib/private/session/internal.php b/lib/private/Session/Internal.php index 09175bf1f2f..09175bf1f2f 100644 --- a/lib/private/session/internal.php +++ b/lib/private/Session/Internal.php diff --git a/lib/private/session/memory.php b/lib/private/Session/Memory.php index 777458a9aa5..777458a9aa5 100644 --- a/lib/private/session/memory.php +++ b/lib/private/Session/Memory.php diff --git a/lib/private/session/session.php b/lib/private/Session/Session.php index 198d0049956..198d0049956 100644 --- a/lib/private/session/session.php +++ b/lib/private/Session/Session.php diff --git a/lib/private/api.php b/lib/private/api.php index 12a78f1424b..bab879c95f8 100644 --- a/lib/private/api.php +++ b/lib/private/api.php @@ -179,7 +179,7 @@ class OC_API { $response = self::mergeResponses($responses); $format = self::requestedFormat(); if (self::$logoutRequired) { - OC_User::logout(); + \OC::$server->getUserSession()->logout(); } self::respond($response, $format); diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index c8525d1d141..7cd8cedcfdd 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -368,7 +368,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { /** * Shortcut for getting cookie variables * @param string $key the key that will be taken from the $_COOKIE array - * @return array the value in the $_COOKIE element + * @return string the value in the $_COOKIE element */ public function getCookie($key) { return isset($this->cookies[$key]) ? $this->cookies[$key] : null; diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php index 75bcc29a926..4afd29cd060 100644 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ b/lib/private/appframework/middleware/security/securitymiddleware.php @@ -192,9 +192,12 @@ class SecurityMiddleware extends Middleware { ); } else { if($exception instanceof NotLoggedInException) { - // TODO: replace with link to route - $url = $this->urlGenerator->getAbsoluteURL('index.php'); - $url .= '?redirect_url=' . urlencode($this->request->server['REQUEST_URI']); + $url = $this->urlGenerator->linkToRoute( + 'core.login.showLoginForm', + [ + 'redirect_url' => urlencode($this->request->server['REQUEST_URI']), + ] + ); $response = new RedirectResponse($url); } else { $response = new TemplateResponse('core', '403', ['file' => $exception->getMessage()], 'guest'); diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php index 0a207de7b64..5ca32548fe0 100644 --- a/lib/private/files/cache/scanner.php +++ b/lib/private/files/cache/scanner.php @@ -448,26 +448,38 @@ class Scanner extends BasicEmitter implements IScanner { * walk over any folders that are not fully scanned yet and scan them */ public function backgroundScan() { - $lastPath = null; - while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { - try { - $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); - \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); - if ($this->cacheActive) { - $this->cache->correctFolderSize($path); - } - } catch (\OCP\Files\StorageInvalidException $e) { - // skip unavailable storages - } catch (\OCP\Files\StorageNotAvailableException $e) { - // skip unavailable storages - } catch (\OCP\Files\ForbiddenException $e) { - // skip forbidden storages - } catch (\OCP\Lock\LockedException $e) { - // skip unavailable storages + if (!$this->cache->inCache('')) { + $this->runBackgroundScanJob(function () { + $this->scan('', self::SCAN_RECURSIVE, self::REUSE_ETAG); + }, ''); + } else { + $lastPath = null; + while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) { + $this->runBackgroundScanJob(function() use ($path) { + $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG); + }, $path); + // FIXME: this won't proceed with the next item, needs revamping of getIncomplete() + // to make this possible + $lastPath = $path; + } + } + } + + private function runBackgroundScanJob(callable $callback, $path) { + try { + $callback(); + \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path)); + if ($this->cacheActive) { + $this->cache->correctFolderSize($path); } - // FIXME: this won't proceed with the next item, needs revamping of getIncomplete() - // to make this possible - $lastPath = $path; + } catch (\OCP\Files\StorageInvalidException $e) { + // skip unavailable storages + } catch (\OCP\Files\StorageNotAvailableException $e) { + // skip unavailable storages + } catch (\OCP\Files\ForbiddenException $e) { + // skip forbidden storages + } catch (\OCP\Lock\LockedException $e) { + // skip unavailable storages } } diff --git a/lib/private/db/statementwrapper.php b/lib/private/legacy/db/statementwrapper.php index 6422d8d5f1b..6422d8d5f1b 100644 --- a/lib/private/db/statementwrapper.php +++ b/lib/private/legacy/db/statementwrapper.php diff --git a/lib/private/share/share.php b/lib/private/share/share.php index c6f7258c536..2125767cabb 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -137,7 +137,7 @@ class Share extends Constants { $publicShare = false; $remoteShare = false; $source = -1; - $cache = false; + $cache = $mountPath = false; $view = new \OC\Files\View('/' . $ownerUser . '/files'); $meta = $view->getFileInfo($path); @@ -151,8 +151,14 @@ class Share extends Constants { if($meta !== false) { $source = $meta['fileid']; $cache = new \OC\Files\Cache\Cache($meta['storage']); + + $mountPath = $meta->getMountPoint()->getMountPoint(); + if ($mountPath !== false) { + $mountPath = substr($mountPath, strlen('/' . $ownerUser . '/files')); + } } + $paths = []; while ($source !== -1) { // Fetch all shares with another user if (!$returnUserPaths) { @@ -257,6 +263,7 @@ class Share extends Constants { // let's get the parent for the next round $meta = $cache->get((int)$source); if ($recursive === true && $meta !== false) { + $paths[$source] = $meta['path']; $source = (int)$meta['parent']; } else { $source = -1; @@ -285,9 +292,15 @@ class Share extends Constants { } else { while ($row = $result->fetchRow()) { foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { - $sharedPath = $shareData['file_target']; - $sharedPath .= substr($path, strlen($row['path']) -5); - $sharePaths[$uid] = $sharedPath; + if ($mountPath !== false) { + $sharedPath = $shareData['file_target']; + $sharedPath .= substr($path, strlen($mountPath) + strlen($paths[$row['fileid']])); + $sharePaths[$uid] = $sharedPath; + } else { + $sharedPath = $shareData['file_target']; + $sharedPath .= substr($path, strlen($row['path']) -5); + $sharePaths[$uid] = $sharedPath; + } } } } diff --git a/lib/private/template/base.php b/lib/private/template/base.php index 72abc38c36c..cfe629b5fbf 100644 --- a/lib/private/template/base.php +++ b/lib/private/template/base.php @@ -55,7 +55,7 @@ class Base { * @param string|false $app_dir * @param string $theme * @param string $app - * @return array + * @return string[] */ protected function getAppTemplateDirs($theme, $app, $serverRoot, $app_dir) { // Check if the app is in the app folder or in the root @@ -74,7 +74,7 @@ class Base { /** * @param string $serverRoot * @param string $theme - * @return array + * @return string[] */ protected function getCoreTemplateDirs($theme, $serverRoot) { return [ @@ -168,8 +168,13 @@ class Base { // Include ob_start(); - include $file; - $data = ob_get_contents(); + try { + include $file; + $data = ob_get_contents(); + } catch (\Exception $e) { + @ob_end_clean(); + throw $e; + } @ob_end_clean(); // Return data diff --git a/lib/private/templatelayout.php b/lib/private/templatelayout.php index fe7638f399d..88077b418a7 100644 --- a/lib/private/templatelayout.php +++ b/lib/private/templatelayout.php @@ -182,7 +182,7 @@ class TemplateLayout extends \OC_Template { \OC::$server->getLogger(), $theme, array( \OC::$SERVERROOT => \OC::$WEBROOT ), - array( \OC::$THIRDPARTYROOT => \OC::$THIRDPARTYWEBROOT )); + array( \OC::$SERVERROOT => \OC::$WEBROOT )); $locator->find($styles); return $locator->getResources(); } @@ -199,7 +199,7 @@ class TemplateLayout extends \OC_Template { \OC::$server->getLogger(), $theme, array( \OC::$SERVERROOT => \OC::$WEBROOT ), - array( \OC::$THIRDPARTYROOT => \OC::$THIRDPARTYWEBROOT )); + array( \OC::$SERVERROOT => \OC::$WEBROOT )); $locator->find($scripts); return $locator->getResources(); } diff --git a/lib/private/updater.php b/lib/private/updater.php index 0d567b8dfb9..627e01596bb 100644 --- a/lib/private/updater.php +++ b/lib/private/updater.php @@ -37,7 +37,6 @@ use OC\Hooks\BasicEmitter; use OC\IntegrityCheck\Checker; use OC_App; use OC_Installer; -use OC_Util; use OCP\IConfig; use OC\Setup; use OCP\ILogger; @@ -56,9 +55,6 @@ class Updater extends BasicEmitter { /** @var ILogger $log */ private $log; - /** @var \OC\HTTPHelper $helper */ - private $httpHelper; - /** @var IConfig */ private $config; @@ -83,16 +79,13 @@ class Updater extends BasicEmitter { ]; /** - * @param HTTPHelper $httpHelper * @param IConfig $config * @param Checker $checker * @param ILogger $log */ - public function __construct(HTTPHelper $httpHelper, - IConfig $config, + public function __construct(IConfig $config, Checker $checker, ILogger $log = null) { - $this->httpHelper = $httpHelper; $this->log = $log; $this->config = $config; $this->checker = $checker; @@ -132,63 +125,6 @@ class Updater extends BasicEmitter { } /** - * Check if a new version is available - * - * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' - * @return array|bool - */ - public function check($updaterUrl = null) { - - // Look up the cache - it is invalidated all 30 minutes - if (((int)$this->config->getAppValue('core', 'lastupdatedat') + 1800) > time()) { - return json_decode($this->config->getAppValue('core', 'lastupdateResult'), true); - } - - if (is_null($updaterUrl)) { - $updaterUrl = 'https://updates.owncloud.com/server/'; - } - - $this->config->setAppValue('core', 'lastupdatedat', time()); - - if ($this->config->getAppValue('core', 'installedat', '') === '') { - $this->config->setAppValue('core', 'installedat', microtime(true)); - } - - $version = \OCP\Util::getVersion(); - $version['installed'] = $this->config->getAppValue('core', 'installedat'); - $version['updated'] = $this->config->getAppValue('core', 'lastupdatedat'); - $version['updatechannel'] = \OC_Util::getChannel(); - $version['edition'] = \OC_Util::getEditionString(); - $version['build'] = \OC_Util::getBuild(); - $versionString = implode('x', $version); - - //fetch xml data from updater - $url = $updaterUrl . '?version=' . $versionString; - - $tmp = []; - $xml = $this->httpHelper->getUrlContent($url); - if ($xml) { - $loadEntities = libxml_disable_entity_loader(true); - $data = @simplexml_load_string($xml); - libxml_disable_entity_loader($loadEntities); - if ($data !== false) { - $tmp['version'] = (string)$data->version; - $tmp['versionstring'] = (string)$data->versionstring; - $tmp['url'] = (string)$data->url; - $tmp['web'] = (string)$data->web; - } else { - libxml_clear_errors(); - } - } else { - $data = []; - } - - // Cache the result - $this->config->setAppValue('core', 'lastupdateResult', json_encode($data)); - return $tmp; - } - - /** * runs the update actions in maintenance mode, does not upgrade the source files * except the main .htaccess file * diff --git a/lib/private/updater/versioncheck.php b/lib/private/updater/versioncheck.php new file mode 100644 index 00000000000..e42a1e2a40c --- /dev/null +++ b/lib/private/updater/versioncheck.php @@ -0,0 +1,133 @@ +<?php +/** + * @author Arthur Schiwon <blizzz@owncloud.com> + * @author Bart Visscher <bartv@thisnet.nl> + * @author Björn Schießle <schiessle@owncloud.com> + * @author Frank Karlitschek <frank@owncloud.org> + * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Lukas Reschke <lukas@owncloud.com> + * @author Morris Jobke <hey@morrisjobke.de> + * @author Robin Appelman <icewind@owncloud.com> + * @author Robin McCorkell <robin@mccorkell.me.uk> + * @author Steffen Lindner <mail@steffen-lindner.de> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Victor Dubiniuk <dubiniuk@owncloud.com> + * @author Vincent Petry <pvince81@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Updater; + +use OC_Util; +use OCP\Http\Client\IClientService; +use OCP\IConfig; +use OC\Setup; +use OCP\Util; + +class VersionCheck { + + /** @var IClientService */ + private $clientService; + + /** @var IConfig */ + private $config; + + /** + * @param IClientService $clientService + * @param IConfig $config + */ + public function __construct(IClientService $clientService, + IConfig $config) { + $this->clientService = $clientService; + $this->config = $config; + } + + + /** + * Check if a new version is available + * + * @param string $updaterUrl the url to check, i.e. 'http://apps.owncloud.com/updater.php' + * @return array|bool + */ + public function check($updaterUrl = null) { + + // Look up the cache - it is invalidated all 30 minutes + if (((int)$this->config->getAppValue('core', 'lastupdatedat') + 1800) > time()) { + return json_decode($this->config->getAppValue('core', 'lastupdateResult'), true); + } + + if (is_null($updaterUrl)) { + $updaterUrl = 'https://updates.owncloud.com/server/'; + } + + $this->config->setAppValue('core', 'lastupdatedat', time()); + + if ($this->config->getAppValue('core', 'installedat', '') === '') { + $this->config->setAppValue('core', 'installedat', microtime(true)); + } + + $version = Util::getVersion(); + $version['installed'] = $this->config->getAppValue('core', 'installedat'); + $version['updated'] = $this->config->getAppValue('core', 'lastupdatedat'); + $version['updatechannel'] = \OC_Util::getChannel(); + $version['edition'] = \OC_Util::getEditionString(); + $version['build'] = \OC_Util::getBuild(); + $versionString = implode('x', $version); + + //fetch xml data from updater + $url = $updaterUrl . '?version=' . $versionString; + + $tmp = []; + $xml = $this->getUrlContent($url); + if ($xml) { + $loadEntities = libxml_disable_entity_loader(true); + $data = @simplexml_load_string($xml); + libxml_disable_entity_loader($loadEntities); + if ($data !== false) { + $tmp['version'] = (string)$data->version; + $tmp['versionstring'] = (string)$data->versionstring; + $tmp['url'] = (string)$data->url; + $tmp['web'] = (string)$data->web; + } else { + libxml_clear_errors(); + } + } else { + $data = []; + } + + // Cache the result + $this->config->setAppValue('core', 'lastupdateResult', json_encode($data)); + return $tmp; + } + + /** + * @codeCoverageIgnore + * @param string $url + * @return bool|resource|string + */ + protected function getUrlContent($url) { + try { + $client = $this->clientService->newClient(); + $response = $client->get($url); + return $response->getBody(); + } catch (\Exception $e) { + return false; + } + } +} + diff --git a/lib/private/user.php b/lib/private/user.php index 26062f503d2..8767a8d5b6d 100644 --- a/lib/private/user.php +++ b/lib/private/user.php @@ -268,15 +268,6 @@ class OC_User { } /** - * Logs the current user out and kills all the session data - * - * Logout, destroys session - */ - public static function logout() { - self::getUserSession()->logout(); - } - - /** * Tries to login the user with HTTP Basic Authentication */ public static function tryBasicAuthLogin() { @@ -342,7 +333,14 @@ class OC_User { return $backend->getLogoutAttribute(); } - return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . urlencode(\OCP\Util::callRegister()) . '"'; + $logoutUrl = \OC::$server->getURLGenerator()->linkToRouteAbsolute( + 'core.login.logout', + [ + 'requesttoken' => \OCP\Util::callRegister(), + ] + ); + + return 'href="'.$logoutUrl.'"'; } /** diff --git a/lib/private/util.php b/lib/private/util.php index 039bc7e9156..7caa1efcf54 100644 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -947,44 +947,6 @@ class OC_Util { } /** - * @param array $errors - * @param string[] $messages - */ - public static function displayLoginPage($errors = array(), $messages = []) { - $parameters = array(); - foreach ($errors as $value) { - $parameters[$value] = true; - } - $parameters['messages'] = $messages; - if (!empty($_REQUEST['user'])) { - $parameters["username"] = $_REQUEST['user']; - $parameters['user_autofocus'] = false; - } else { - $parameters["username"] = ''; - $parameters['user_autofocus'] = true; - } - if (isset($_REQUEST['redirect_url'])) { - $parameters['redirect_url'] = $_REQUEST['redirect_url']; - } - - $parameters['canResetPassword'] = true; - if (!\OC::$server->getSystemConfig()->getValue('lost_password_link')) { - if (isset($_REQUEST['user'])) { - $user = \OC::$server->getUserManager()->get($_REQUEST['user']); - if ($user instanceof IUser) { - $parameters['canResetPassword'] = $user->canChangePassword(); - } - } - } - - $parameters['alt_login'] = OC_App::getAlternativeLogIns(); - $parameters['rememberLoginAllowed'] = self::rememberLoginAllowed(); - $parameters['rememberLoginState'] = isset($_POST['remember_login']) ? $_POST['remember_login'] : 0; - \OC_Hook::emit('OC_Util', 'pre_displayLoginPage', array('parameters' => $parameters)); - OC_Template::printGuestPage("", "login", $parameters); - } - - /** * Check if the user is logged in, redirects to home if not. With * redirect URL parameter to the request URI. * @@ -993,7 +955,8 @@ class OC_Util { public static function checkLoggedIn() { // Check if we are a user if (!OC_User::isLoggedIn()) { - header('Location: ' . \OCP\Util::linkToAbsolute('', 'index.php', + header('Location: ' . \OC::$server->getURLGenerator()->linkToRoute( + 'core.login.showLoginForm', [ 'redirect_url' => \OC::$server->getRequest()->getRequestUri() ] diff --git a/lib/public/irequest.php b/lib/public/irequest.php index a0040aa464d..296c70f4ecc 100644 --- a/lib/public/irequest.php +++ b/lib/public/irequest.php @@ -129,7 +129,7 @@ interface IRequest { * Shortcut for getting cookie variables * * @param string $key the key that will be taken from the $_COOKIE array - * @return array the value in the $_COOKIE element + * @return string the value in the $_COOKIE element * @since 6.0.0 */ public function getCookie($key); diff --git a/lib/public/user.php b/lib/public/user.php index 825e77aef6d..64ac92d2100 100644 --- a/lib/public/user.php +++ b/lib/public/user.php @@ -119,7 +119,7 @@ class User { * @since 5.0.0 */ public static function logout() { - \OC_User::logout(); + \OC::$server->getUserSession()->logout(); } /** diff --git a/remote.php b/remote.php index 86b47629d73..814286860af 100644 --- a/remote.php +++ b/remote.php @@ -108,6 +108,11 @@ function resolveService($service) { try { require_once 'lib/base.php'; + // All resources served via the DAV endpoint should have the strictest possible + // policy. Exempted from this is the SabreDAV browser plugin which overwrites + // this policy with a softer one if debug mode is enabled. + header("Content-Security-Policy: default-src 'none';"); + if (\OCP\Util::needUpgrade()) { // since the behavior of apps or remotes are unpredictable during // an upgrade, return a 503 directly diff --git a/settings/js/users/deleteHandler.js b/settings/js/users/deleteHandler.js index b684aff1889..a66e8b07a72 100644 --- a/settings/js/users/deleteHandler.js +++ b/settings/js/users/deleteHandler.js @@ -191,7 +191,7 @@ DeleteHandler.prototype.deleteEntry = function(keepNotification) { payload[dh.ajaxParamID] = dh.oidToDelete; return $.ajax({ type: 'DELETE', - url: OC.generateUrl(dh.ajaxEndpoint+'/'+this.oidToDelete), + url: OC.generateUrl(dh.ajaxEndpoint+'/{oid}',{oid: this.oidToDelete}), // FIXME: do not use synchronous ajax calls as they block the browser ! async: false, success: function (result) { diff --git a/settings/l10n/cs_CZ.js b/settings/l10n/cs_CZ.js index 1b5c3efaa86..859e37de617 100644 --- a/settings/l10n/cs_CZ.js +++ b/settings/l10n/cs_CZ.js @@ -63,6 +63,7 @@ OC.L10N.register( "Experimental" : "Experimentální", "All" : "Vše", "No apps found for your version" : "Nebyly nalezeny aplikace pro vaši verzi", + "The app will be downloaded from the app store" : "Aplikace bude stažena z obchodu aplikací", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Oficiální aplikace jsou vyvíjeny komunitou ownCloud. Nabízejí funkce důležité pro ownCloud a jsou připraveny pro nasazení v produkčním prostředí.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Schválené aplikace jsou vyvíjeny důvěryhodnými vývojáři a prošly zběžným bezpečnostním prověřením. Jsou aktivně udržovány v repozitáři s otevřeným kódem a jejich správci je považují za stabilní pro občasné až normální použití.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "U této aplikace nebyla provedena kontrola na bezpečnostní problémy. Aplikace je nová nebo nestabilní. Instalujte pouze na vlastní nebezpečí.", diff --git a/settings/l10n/cs_CZ.json b/settings/l10n/cs_CZ.json index 1210640b7b3..62baeb34ee7 100644 --- a/settings/l10n/cs_CZ.json +++ b/settings/l10n/cs_CZ.json @@ -61,6 +61,7 @@ "Experimental" : "Experimentální", "All" : "Vše", "No apps found for your version" : "Nebyly nalezeny aplikace pro vaši verzi", + "The app will be downloaded from the app store" : "Aplikace bude stažena z obchodu aplikací", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Oficiální aplikace jsou vyvíjeny komunitou ownCloud. Nabízejí funkce důležité pro ownCloud a jsou připraveny pro nasazení v produkčním prostředí.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Schválené aplikace jsou vyvíjeny důvěryhodnými vývojáři a prošly zběžným bezpečnostním prověřením. Jsou aktivně udržovány v repozitáři s otevřeným kódem a jejich správci je považují za stabilní pro občasné až normální použití.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "U této aplikace nebyla provedena kontrola na bezpečnostní problémy. Aplikace je nová nebo nestabilní. Instalujte pouze na vlastní nebezpečí.", diff --git a/settings/l10n/es.js b/settings/l10n/es.js index bb530a7e974..39431fc813e 100644 --- a/settings/l10n/es.js +++ b/settings/l10n/es.js @@ -63,6 +63,7 @@ OC.L10N.register( "Experimental" : "Experimental", "All" : "Todos", "No apps found for your version" : "No se han encontrado aplicaciones para su versión", + "The app will be downloaded from the app store" : "La app debe ser descargada desde una app store", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplicaciones oficiales son desarrolladas por y dentro de la comunidad ownCloud. Estas ofrecen una funcionalidad central con ownCloud y están listas para su uso en producción. ", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Las aplicaciones aprobadas son desarrolladas por desarrolladores de confianza y han pasado un control de seguridad superficial. Estas se mantienen activamente en un repositorio de código abierto y sus mantenedores las consideran estables para un uso normal.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Esta aplicación no está verificada por problemas de seguridad además de ser reciente o conocida por ser inestable. Instálela bajo su propio riesgo.", @@ -84,6 +85,7 @@ OC.L10N.register( "Uninstall" : "Desinstalar", "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "La aplicación ha sido activada pero necesita ser actualizada. Seras redirigido a la pagina de actualizariones en 5 segundos.", "App update" : "Actualización de aplicación", + "No apps found for {query}" : "No se han encontrado apps para {query}", "An error occurred. Please upload an ASCII-encoded PEM certificate." : "Ha ocurrido un error. Por favor, cargue un certificado PEM codificado en ASCII.", "Valid until {date}" : "Válido hasta {date}", "Delete" : "Eliminar", diff --git a/settings/l10n/es.json b/settings/l10n/es.json index 1d6b47a20bf..b135cbfdd72 100644 --- a/settings/l10n/es.json +++ b/settings/l10n/es.json @@ -61,6 +61,7 @@ "Experimental" : "Experimental", "All" : "Todos", "No apps found for your version" : "No se han encontrado aplicaciones para su versión", + "The app will be downloaded from the app store" : "La app debe ser descargada desde una app store", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplicaciones oficiales son desarrolladas por y dentro de la comunidad ownCloud. Estas ofrecen una funcionalidad central con ownCloud y están listas para su uso en producción. ", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Las aplicaciones aprobadas son desarrolladas por desarrolladores de confianza y han pasado un control de seguridad superficial. Estas se mantienen activamente en un repositorio de código abierto y sus mantenedores las consideran estables para un uso normal.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Esta aplicación no está verificada por problemas de seguridad además de ser reciente o conocida por ser inestable. Instálela bajo su propio riesgo.", @@ -82,6 +83,7 @@ "Uninstall" : "Desinstalar", "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "La aplicación ha sido activada pero necesita ser actualizada. Seras redirigido a la pagina de actualizariones en 5 segundos.", "App update" : "Actualización de aplicación", + "No apps found for {query}" : "No se han encontrado apps para {query}", "An error occurred. Please upload an ASCII-encoded PEM certificate." : "Ha ocurrido un error. Por favor, cargue un certificado PEM codificado en ASCII.", "Valid until {date}" : "Válido hasta {date}", "Delete" : "Eliminar", diff --git a/settings/l10n/fi_FI.js b/settings/l10n/fi_FI.js index 3fe0d0711ac..0e438ae7445 100644 --- a/settings/l10n/fi_FI.js +++ b/settings/l10n/fi_FI.js @@ -62,6 +62,7 @@ OC.L10N.register( "Experimental" : "Kokeellinen", "All" : "Kaikki", "No apps found for your version" : "Sovelluksia ei löytynyt versiollesi", + "The app will be downloaded from the app store" : "Sovellus ladataan sovelluskaupasta", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Viralliset sovellukset kehitetään ownCloud-yhteisön toimesta. Sovellukset tarjoavat lisäominaisuuksia ownCloudin keskeisiin toimintoihin liittyen ja ovat valmiita tuotantokäyttöön.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Hyväksytyt sovellukset on kehitetty luotettujen kehittäjien toimesta. Hyväksytyille sovelluksille on suoritettu pintapuolinen turvallisuustarkastus. Sovelluksia ylläpidetään avoimen koodin tietovarastoissa. Sovellusten kehittäjät mieltävät sovellukset vakaiksi ja valmiiksi tavalliseen käyttöön.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Tätä sovellusta ei ole tarkistettu tietoturvauhkien varalta. Sovellus on uusi ja mahdollisesti tiedostettu epävakaaksi. Asenna omalla vastuulla.", diff --git a/settings/l10n/fi_FI.json b/settings/l10n/fi_FI.json index b638e0ff2f9..768f7e46b39 100644 --- a/settings/l10n/fi_FI.json +++ b/settings/l10n/fi_FI.json @@ -60,6 +60,7 @@ "Experimental" : "Kokeellinen", "All" : "Kaikki", "No apps found for your version" : "Sovelluksia ei löytynyt versiollesi", + "The app will be downloaded from the app store" : "Sovellus ladataan sovelluskaupasta", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Viralliset sovellukset kehitetään ownCloud-yhteisön toimesta. Sovellukset tarjoavat lisäominaisuuksia ownCloudin keskeisiin toimintoihin liittyen ja ovat valmiita tuotantokäyttöön.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Hyväksytyt sovellukset on kehitetty luotettujen kehittäjien toimesta. Hyväksytyille sovelluksille on suoritettu pintapuolinen turvallisuustarkastus. Sovelluksia ylläpidetään avoimen koodin tietovarastoissa. Sovellusten kehittäjät mieltävät sovellukset vakaiksi ja valmiiksi tavalliseen käyttöön.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Tätä sovellusta ei ole tarkistettu tietoturvauhkien varalta. Sovellus on uusi ja mahdollisesti tiedostettu epävakaaksi. Asenna omalla vastuulla.", diff --git a/settings/l10n/it.js b/settings/l10n/it.js index f6e5535929f..09f49c21312 100644 --- a/settings/l10n/it.js +++ b/settings/l10n/it.js @@ -63,6 +63,7 @@ OC.L10N.register( "Experimental" : "Sperimentale", "All" : "Tutti", "No apps found for your version" : "Nessuna applicazione trovata per la tua versione", + "The app will be downloaded from the app store" : "L'applicazione sarà scaricata dallo store delle applicazioni", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Le applicazioni ufficiali sono sviluppate da e con la comunità di ownCloud. Offrono le funzioni fondamentali di ownCloud e sono pronte per l'utilizzo in produzione.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Le applicazioni approvate sono sviluppate da sviluppatori affidabili e hanno passato un rapido controllo di sicurezza. Sono attivamente mantenute in un deposito aperto del codice e i loro responsabili le ritengono pronte sia per un utilizzo casuale che per un utilizzo continuativo.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Questa applicazione non è stata sottoposta a controlli di sicurezza, è nuova o notoriamente instabile. Installala a tuo rischio.", diff --git a/settings/l10n/it.json b/settings/l10n/it.json index 780c2233e97..11a91a2ed4f 100644 --- a/settings/l10n/it.json +++ b/settings/l10n/it.json @@ -61,6 +61,7 @@ "Experimental" : "Sperimentale", "All" : "Tutti", "No apps found for your version" : "Nessuna applicazione trovata per la tua versione", + "The app will be downloaded from the app store" : "L'applicazione sarà scaricata dallo store delle applicazioni", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Le applicazioni ufficiali sono sviluppate da e con la comunità di ownCloud. Offrono le funzioni fondamentali di ownCloud e sono pronte per l'utilizzo in produzione.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Le applicazioni approvate sono sviluppate da sviluppatori affidabili e hanno passato un rapido controllo di sicurezza. Sono attivamente mantenute in un deposito aperto del codice e i loro responsabili le ritengono pronte sia per un utilizzo casuale che per un utilizzo continuativo.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Questa applicazione non è stata sottoposta a controlli di sicurezza, è nuova o notoriamente instabile. Installala a tuo rischio.", diff --git a/settings/l10n/pt_BR.js b/settings/l10n/pt_BR.js index ece7ecc3b93..80856cc52fa 100644 --- a/settings/l10n/pt_BR.js +++ b/settings/l10n/pt_BR.js @@ -63,6 +63,7 @@ OC.L10N.register( "Experimental" : "Experimental", "All" : "Todos", "No apps found for your version" : "Nenhum aplicativo encontrados para a sua versão", + "The app will be downloaded from the app store" : "O aplicativo será baixado na App Store", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplicativos oficiais são desenvolvidos por e dentro da comunidade ownCloud. Eles oferecem funcionalidade central para ownCloud e estão prontos para uso em produção.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Aplicativos aprovados são desenvolvidos pelos desenvolvedores confiáveis e passaram por uma verificação de segurança superficial. Eles são ativamente mantidos em um repositório de código aberto e seus mantenedores consideram que eles para sejam estáveis para um casual uso normal.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Este aplicativo não foi verificado para as questões de segurança e é novo ou conhecido por ser instável. Instale por seu próprio risco.", diff --git a/settings/l10n/pt_BR.json b/settings/l10n/pt_BR.json index 35374c52863..1a724f7c7a1 100644 --- a/settings/l10n/pt_BR.json +++ b/settings/l10n/pt_BR.json @@ -61,6 +61,7 @@ "Experimental" : "Experimental", "All" : "Todos", "No apps found for your version" : "Nenhum aplicativo encontrados para a sua versão", + "The app will be downloaded from the app store" : "O aplicativo será baixado na App Store", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplicativos oficiais são desenvolvidos por e dentro da comunidade ownCloud. Eles oferecem funcionalidade central para ownCloud e estão prontos para uso em produção.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Aplicativos aprovados são desenvolvidos pelos desenvolvedores confiáveis e passaram por uma verificação de segurança superficial. Eles são ativamente mantidos em um repositório de código aberto e seus mantenedores consideram que eles para sejam estáveis para um casual uso normal.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Este aplicativo não foi verificado para as questões de segurança e é novo ou conhecido por ser instável. Instale por seu próprio risco.", diff --git a/settings/l10n/sq.js b/settings/l10n/sq.js index 9e3f9be212f..d2e5d1b6537 100644 --- a/settings/l10n/sq.js +++ b/settings/l10n/sq.js @@ -63,6 +63,7 @@ OC.L10N.register( "Experimental" : "Eksperimentale", "All" : "Krejt", "No apps found for your version" : "S’u gjetën aplikacione për versionin tuaj", + "The app will be downloaded from the app store" : "Aplikacioni do të shkarkohet nga shitorja e aplikacioneve", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplikacionet zyrtare ndërtohen brenda bashkësisë ownCloud. Ato ofrojnë funksione qendrore për ownCloud dhe janë gati për t’u përdorur në prodhim.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Aplikacionet e miratuara ndërtohen nga zhvillues të besuar dhe kanë kaluar një kontroll të përciptë sigurie. Mirëmbahen aktivisht në një depo të hapur kodi dhe mirëmbajtësit e tyre i konsiderojnë të qëndrueshme për përdorime nga të rastit deri në ato normale.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Ky aplikacion s’është kontrolluar për probleme sigurie dhe është i ri ose i njohur si i paqëndrueshëm. Instalojeni duke e mbajtur vetë përgjegjësinë.", diff --git a/settings/l10n/sq.json b/settings/l10n/sq.json index 50415cca870..e00f1f6560a 100644 --- a/settings/l10n/sq.json +++ b/settings/l10n/sq.json @@ -61,6 +61,7 @@ "Experimental" : "Eksperimentale", "All" : "Krejt", "No apps found for your version" : "S’u gjetën aplikacione për versionin tuaj", + "The app will be downloaded from the app store" : "Aplikacioni do të shkarkohet nga shitorja e aplikacioneve", "Official apps are developed by and within the ownCloud community. They offer functionality central to ownCloud and are ready for production use." : "Aplikacionet zyrtare ndërtohen brenda bashkësisë ownCloud. Ato ofrojnë funksione qendrore për ownCloud dhe janë gati për t’u përdorur në prodhim.", "Approved apps are developed by trusted developers and have passed a cursory security check. They are actively maintained in an open code repository and their maintainers deem them to be stable for casual to normal use." : "Aplikacionet e miratuara ndërtohen nga zhvillues të besuar dhe kanë kaluar një kontroll të përciptë sigurie. Mirëmbahen aktivisht në një depo të hapur kodi dhe mirëmbajtësit e tyre i konsiderojnë të qëndrueshme për përdorime nga të rastit deri në ato normale.", "This app is not checked for security issues and is new or known to be unstable. Install at your own risk." : "Ky aplikacion s’është kontrolluar për probleme sigurie dhe është i ri ose i njohur si i paqëndrueshëm. Instalojeni duke e mbajtur vetë përgjegjësinë.", diff --git a/settings/l10n/sv.js b/settings/l10n/sv.js index 404e6319125..e3758adc2f5 100644 --- a/settings/l10n/sv.js +++ b/settings/l10n/sv.js @@ -84,6 +84,7 @@ OC.L10N.register( "Uninstall" : "Avinstallera", "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "Applikationen har aktiverats men behöver uppdateras. Du kommer bli omdirigerad till uppdateringssidan inom 5 sekunder.", "App update" : "Uppdatering av app", + "No apps found for {query}" : "Inga applikationer funna för {query}", "An error occurred. Please upload an ASCII-encoded PEM certificate." : "Ett fel uppstod. Var god ladda upp ett ASCII-kodad PEM certifikat.", "Valid until {date}" : "Giltig t.o.m. {date}", "Delete" : "Radera", diff --git a/settings/l10n/sv.json b/settings/l10n/sv.json index 8aff721bd50..0a56fda47ec 100644 --- a/settings/l10n/sv.json +++ b/settings/l10n/sv.json @@ -82,6 +82,7 @@ "Uninstall" : "Avinstallera", "The app has been enabled but needs to be updated. You will be redirected to the update page in 5 seconds." : "Applikationen har aktiverats men behöver uppdateras. Du kommer bli omdirigerad till uppdateringssidan inom 5 sekunder.", "App update" : "Uppdatering av app", + "No apps found for {query}" : "Inga applikationer funna för {query}", "An error occurred. Please upload an ASCII-encoded PEM certificate." : "Ett fel uppstod. Var god ladda upp ett ASCII-kodad PEM certifikat.", "Valid until {date}" : "Giltig t.o.m. {date}", "Delete" : "Radera", diff --git a/settings/tests/js/users/deleteHandlerSpec.js b/settings/tests/js/users/deleteHandlerSpec.js index 371eae5941d..3e7f768e519 100644 --- a/settings/tests/js/users/deleteHandlerSpec.js +++ b/settings/tests/js/users/deleteHandlerSpec.js @@ -132,6 +132,20 @@ describe('DeleteHandler tests', function() { var request = fakeServer.requests[0]; expect(request.url).toEqual(OC.webroot + '/index.php/dummyendpoint.php/some_uid'); }); + it('deletes when deleteEntry is called and escapes', function() { + fakeServer.respondWith(/\/index\.php\/dummyendpoint.php\/some_uid/, [ + 200, + { 'Content-Type': 'application/json' }, + JSON.stringify({status: 'success'}) + ]); + var handler = init(markCallback, removeCallback, undoCallback); + handler.mark('some_uid<>/"..\\'); + + handler.deleteEntry(); + expect(fakeServer.requests.length).toEqual(1); + var request = fakeServer.requests[0]; + expect(request.url).toEqual(OC.webroot + '/index.php/dummyendpoint.php/some_uid%3C%3E%2F%22..%5C'); + }); it('cancels deletion when undo is clicked', function() { var handler = init(markCallback, removeCallback, undoCallback); handler.setNotification(OC.Notification, 'dataid', 'removed %oid entry <span class="undo">Undo</span>', undoCallback); diff --git a/tests/core/controller/LoginControllerTest.php b/tests/core/controller/LoginControllerTest.php new file mode 100644 index 00000000000..f9a6080892b --- /dev/null +++ b/tests/core/controller/LoginControllerTest.php @@ -0,0 +1,267 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC\Core\Controller; + +use OCP\AppFramework\Http\RedirectResponse; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; +use OCP\IRequest; +use OCP\ISession; +use OCP\IURLGenerator; +use OCP\IUserManager; +use OCP\IUserSession; +use Test\TestCase; + +class LoginControllerTest extends TestCase { + /** @var LoginController */ + private $loginController; + /** @var IRequest */ + private $request; + /** @var IUserManager */ + private $userManager; + /** @var IConfig */ + private $config; + /** @var ISession */ + private $session; + /** @var IUserSession */ + private $userSession; + /** @var IURLGenerator */ + private $urlGenerator; + + public function setUp() { + parent::setUp(); + $this->request = $this->getMock('\\OCP\\IRequest'); + $this->userManager = $this->getMock('\\OCP\\IUserManager'); + $this->config = $this->getMock('\\OCP\\IConfig'); + $this->session = $this->getMock('\\OCP\\ISession'); + $this->userSession = $this->getMock('\\OCP\\IUserSession'); + $this->urlGenerator = $this->getMock('\\OCP\\IURLGenerator'); + + $this->loginController = new LoginController( + 'core', + $this->request, + $this->userManager, + $this->config, + $this->session, + $this->userSession, + $this->urlGenerator + ); + } + + public function testLogoutWithoutToken() { + $this->request + ->expects($this->once()) + ->method('getCookie') + ->with('oc_token') + ->willReturn(null); + $this->config + ->expects($this->never()) + ->method('deleteUserValue'); + $this->urlGenerator + ->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with('core.login.showLoginForm') + ->willReturn('/login'); + + $expected = new RedirectResponse('/login'); + $this->assertEquals($expected, $this->loginController->logout()); + } + + public function testLogoutWithToken() { + $this->request + ->expects($this->once()) + ->method('getCookie') + ->with('oc_token') + ->willReturn('MyLoginToken'); + $user = $this->getMock('\\OCP\\IUser'); + $user + ->expects($this->once()) + ->method('getUID') + ->willReturn('JohnDoe'); + $this->userSession + ->expects($this->once()) + ->method('getUser') + ->willReturn($user); + $this->config + ->expects($this->once()) + ->method('deleteUserValue') + ->with('JohnDoe', 'login_token', 'MyLoginToken'); + $this->urlGenerator + ->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with('core.login.showLoginForm') + ->willReturn('/login'); + + $expected = new RedirectResponse('/login'); + $this->assertEquals($expected, $this->loginController->logout()); + } + + public function testShowLoginFormForLoggedInUsers() { + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(true); + + $expectedResponse = new RedirectResponse(\OC_Util::getDefaultPageUrl()); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', '')); + } + + public function testShowLoginFormWithErrorsInSession() { + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(false); + $this->session + ->expects($this->once()) + ->method('get') + ->with('loginMessages') + ->willReturn( + [ + [ + 'ErrorArray1', + 'ErrorArray2', + ], + [ + 'MessageArray1', + 'MessageArray2', + ], + ] + ); + + $expectedResponse = new TemplateResponse( + 'core', + 'login', + [ + 'ErrorArray1' => true, + 'ErrorArray2' => true, + 'messages' => [ + 'MessageArray1', + 'MessageArray2', + ], + 'loginName' => '', + 'user_autofocus' => true, + 'canResetPassword' => true, + 'alt_login' => [], + 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(), + 'rememberLoginState' => 0, + ], + 'guest' + ); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', '')); + } + + /** + * @return array + */ + public function passwordResetDataProvider() { + return [ + [ + true, + true, + ], + [ + false, + false, + ], + ]; + } + + /** + * @dataProvider passwordResetDataProvider + */ + public function testShowLoginFormWithPasswordResetOption($canChangePassword, + $expectedResult) { + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(false); + $this->config + ->expects($this->once()) + ->method('getSystemValue') + ->with('lost_password_link') + ->willReturn(false); + $user = $this->getMock('\\OCP\\IUser'); + $user + ->expects($this->once()) + ->method('canChangePassword') + ->willReturn($canChangePassword); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('LdapUser') + ->willReturn($user); + + $expectedResponse = new TemplateResponse( + 'core', + 'login', + [ + 'messages' => [], + 'loginName' => 'LdapUser', + 'user_autofocus' => false, + 'canResetPassword' => $expectedResult, + 'alt_login' => [], + 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(), + 'rememberLoginState' => 0, + ], + 'guest' + ); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('LdapUser', '', '')); + } + + public function testShowLoginFormForUserNamedNull() { + $this->userSession + ->expects($this->once()) + ->method('isLoggedIn') + ->willReturn(false); + $this->config + ->expects($this->once()) + ->method('getSystemValue') + ->with('lost_password_link') + ->willReturn(false); + $user = $this->getMock('\\OCP\\IUser'); + $user + ->expects($this->once()) + ->method('canChangePassword') + ->willReturn(false); + $this->userManager + ->expects($this->once()) + ->method('get') + ->with('0') + ->willReturn($user); + + $expectedResponse = new TemplateResponse( + 'core', + 'login', + [ + 'messages' => [], + 'loginName' => '0', + 'user_autofocus' => false, + 'canResetPassword' => false, + 'alt_login' => [], + 'rememberLoginAllowed' => \OC_Util::rememberLoginAllowed(), + 'rememberLoginState' => 0, + ], + 'guest' + ); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('0', '', '')); + } +} diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php index 9e71a3d0961..dd4ec3af96f 100644 --- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -343,9 +343,14 @@ class SecurityMiddlewareTest extends \Test\TestCase { $this->middleware = $this->getMiddleware(false, false); $this->urlGenerator ->expects($this->once()) - ->method('getAbsoluteURL') - ->with('index.php') - ->will($this->returnValue('http://localhost/index.php')); + ->method('linkToRoute') + ->with( + 'core.login.showLoginForm', + [ + 'redirect_url' => 'owncloud%2Findex.php%2Fapps%2Fspecialapp', + ] + ) + ->will($this->returnValue('http://localhost/index.php/login?redirect_url=owncloud%2Findex.php%2Fapps%2Fspecialapp')); $this->logger ->expects($this->once()) ->method('debug') @@ -356,7 +361,7 @@ class SecurityMiddlewareTest extends \Test\TestCase { new NotLoggedInException() ); - $expected = new RedirectResponse('http://localhost/index.php?redirect_url=owncloud%2Findex.php%2Fapps%2Fspecialapp'); + $expected = new RedirectResponse('http://localhost/index.php/login?redirect_url=owncloud%2Findex.php%2Fapps%2Fspecialapp'); $this->assertEquals($expected , $response); } diff --git a/tests/lib/updater.php b/tests/lib/updater.php index 8ee77b9f81e..f97eb3ac139 100644 --- a/tests/lib/updater.php +++ b/tests/lib/updater.php @@ -29,8 +29,6 @@ use OC\IntegrityCheck\Checker; class UpdaterTest extends \Test\TestCase { /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */ private $config; - /** @var HTTPHelper */ - private $httpHelper; /** @var ILogger */ private $logger; /** @var Updater */ @@ -43,9 +41,6 @@ class UpdaterTest extends \Test\TestCase { $this->config = $this->getMockBuilder('\\OCP\\IConfig') ->disableOriginalConstructor() ->getMock(); - $this->httpHelper = $this->getMockBuilder('\\OC\\HTTPHelper') - ->disableOriginalConstructor() - ->getMock(); $this->logger = $this->getMockBuilder('\\OCP\\ILogger') ->disableOriginalConstructor() ->getMock(); @@ -54,7 +49,6 @@ class UpdaterTest extends \Test\TestCase { ->getMock(); $this->updater = new Updater( - $this->httpHelper, $this->config, $this->checker, $this->logger @@ -184,237 +178,4 @@ class UpdaterTest extends \Test\TestCase { $this->assertSame(false, $this->invokePrivate($this->updater, 'skip3rdPartyAppsDisable')); } - public function testCheckInCache() { - $expectedResult = [ - 'version' => '8.0.4.2', - 'versionstring' => 'ownCloud 8.0.4', - 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', - 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', - ]; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(time())); - $this->config - ->expects($this->at(1)) - ->method('getAppValue') - ->with('core', 'lastupdateResult') - ->will($this->returnValue(json_encode($expectedResult))); - - $this->assertSame($expectedResult, $this->updater->check()); - } - - public function testCheckWithoutUpdateUrl() { - $expectedResult = [ - 'version' => '8.0.4.2', - 'versionstring' => 'ownCloud 8.0.4', - 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', - 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', - ]; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(0)); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('core', 'lastupdatedat', $this->isType('integer')); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('core', 'installedat') - ->will($this->returnValue('installedat')); - $this->config - ->expects($this->at(4)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue('lastupdatedat')); - $this->config - ->expects($this->at(5)) - ->method('setAppValue') - ->with('core', 'lastupdateResult', json_encode($expectedResult)); - - $updateXml = '<?xml version="1.0"?> -<owncloud> - <version>8.0.4.2</version> - <versionstring>ownCloud 8.0.4</versionstring> - <url>https://download.owncloud.org/community/owncloud-8.0.4.zip</url> - <web>http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html</web> -</owncloud>'; - $this->httpHelper - ->expects($this->once()) - ->method('getUrlContent') - ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) - ->will($this->returnValue($updateXml)); - - $this->assertSame($expectedResult, $this->updater->check()); - } - - public function testCheckWithInvalidXml() { - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(0)); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('core', 'lastupdatedat', $this->isType('integer')); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('core', 'installedat') - ->will($this->returnValue('installedat')); - $this->config - ->expects($this->at(4)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue('lastupdatedat')); - $this->config - ->expects($this->at(5)) - ->method('setAppValue') - ->with('core', 'lastupdateResult', 'false'); - - $updateXml = 'Invalid XML Response!'; - $this->httpHelper - ->expects($this->once()) - ->method('getUrlContent') - ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) - ->will($this->returnValue($updateXml)); - - $this->assertSame([], $this->updater->check()); - } - - public function testCheckWithUpdateUrl() { - $expectedResult = [ - 'version' => '8.0.4.2', - 'versionstring' => 'ownCloud 8.0.4', - 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', - 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', - ]; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(0)); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('core', 'lastupdatedat', $this->isType('integer')); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('core', 'installedat') - ->will($this->returnValue('installedat')); - $this->config - ->expects($this->at(4)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue('lastupdatedat')); - $this->config - ->expects($this->at(5)) - ->method('setAppValue') - ->with('core', 'lastupdateResult', json_encode($expectedResult)); - - $updateXml = '<?xml version="1.0"?> -<owncloud> - <version>8.0.4.2</version> - <versionstring>ownCloud 8.0.4</versionstring> - <url>https://download.owncloud.org/community/owncloud-8.0.4.zip</url> - <web>http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html</web> -</owncloud>'; - $this->httpHelper - ->expects($this->once()) - ->method('getUrlContent') - ->with($this->buildUpdateUrl('https://myupdater.com/')) - ->will($this->returnValue($updateXml)); - - $this->assertSame($expectedResult, $this->updater->check('https://myupdater.com/')); - } - - public function testCheckWithEmptyValidXmlResponse() { - $expectedResult = [ - 'version' => '', - 'versionstring' => '', - 'url' => '', - 'web' => '', - ]; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(0)); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('core', 'lastupdatedat', $this->isType('integer')); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('core', 'installedat') - ->will($this->returnValue('installedat')); - $this->config - ->expects($this->at(4)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue('lastupdatedat')); - - $updateXml = '<?xml version="1.0"?> -<owncloud> - <version></version> - <versionstring></versionstring> - <url></url> - <web></web> -</owncloud>'; - $this->httpHelper - ->expects($this->once()) - ->method('getUrlContent') - ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) - ->will($this->returnValue($updateXml)); - - $this->assertSame($expectedResult, $this->updater->check()); - } - - public function testCheckWithEmptyInvalidXmlResponse() { - $expectedResult = []; - - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue(0)); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('core', 'lastupdatedat', $this->isType('integer')); - $this->config - ->expects($this->at(3)) - ->method('getAppValue') - ->with('core', 'installedat') - ->will($this->returnValue('installedat')); - $this->config - ->expects($this->at(4)) - ->method('getAppValue') - ->with('core', 'lastupdatedat') - ->will($this->returnValue('lastupdatedat')); - $this->config - ->expects($this->at(5)) - ->method('setAppValue') - ->with('core', 'lastupdateResult', json_encode($expectedResult)); - - $updateXml = ''; - $this->httpHelper - ->expects($this->once()) - ->method('getUrlContent') - ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) - ->will($this->returnValue($updateXml)); - - $this->assertSame($expectedResult, $this->updater->check()); - } } diff --git a/tests/lib/updater/versioncheck.php b/tests/lib/updater/versioncheck.php new file mode 100644 index 00000000000..4613581a75f --- /dev/null +++ b/tests/lib/updater/versioncheck.php @@ -0,0 +1,289 @@ +<?php +/** + * @author Lukas Reschke <lukas@owncloud.com> + * @author Victor Dubiniuk <dubiniuk@owncloud.com> + * + * @copyright Copyright (c) 2015, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OC; + +use OC\Updater\VersionCheck; +use OCP\IConfig; +use OCP\Util; + +class VersionCheckTest extends \Test\TestCase { + /** @var IConfig| \PHPUnit_Framework_MockObject_MockObject */ + private $config; + /** @var VersionCheck | \PHPUnit_Framework_MockObject_MockObject*/ + private $updater; + + public function setUp() { + parent::setUp(); + $this->config = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor() + ->getMock(); + $clientService = $this->getMockBuilder('\OCP\Http\Client\IClientService') + ->disableOriginalConstructor() + ->getMock(); + + $this->updater = $this->getMock('\OC\Updater\VersionCheck', + ['getUrlContent'], [$clientService, $this->config]); + } + + /** + * @param string $baseUrl + * @return string + */ + private function buildUpdateUrl($baseUrl) { + return $baseUrl . '?version='.implode('x', Util::getVersion()).'xinstalledatxlastupdatedatx'.\OC_Util::getChannel().'x'.\OC_Util::getEditionString().'x'; + } + + public function testCheckInCache() { + $expectedResult = [ + 'version' => '8.0.4.2', + 'versionstring' => 'ownCloud 8.0.4', + 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', + 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', + ]; + + $this->config + ->expects($this->at(0)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue(time())); + $this->config + ->expects($this->at(1)) + ->method('getAppValue') + ->with('core', 'lastupdateResult') + ->will($this->returnValue(json_encode($expectedResult))); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithoutUpdateUrl() { + $expectedResult = [ + 'version' => '8.0.4.2', + 'versionstring' => 'ownCloud 8.0.4', + 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', + 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', + ]; + + $this->config + ->expects($this->at(0)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue(0)); + $this->config + ->expects($this->at(1)) + ->method('setAppValue') + ->with('core', 'lastupdatedat', $this->isType('integer')); + $this->config + ->expects($this->at(3)) + ->method('getAppValue') + ->with('core', 'installedat') + ->will($this->returnValue('installedat')); + $this->config + ->expects($this->at(4)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue('lastupdatedat')); + $this->config + ->expects($this->at(5)) + ->method('setAppValue') + ->with('core', 'lastupdateResult', json_encode($expectedResult)); + + $updateXml = '<?xml version="1.0"?> +<owncloud> + <version>8.0.4.2</version> + <versionstring>ownCloud 8.0.4</versionstring> + <url>https://download.owncloud.org/community/owncloud-8.0.4.zip</url> + <web>http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html</web> +</owncloud>'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) + ->will($this->returnValue($updateXml)); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithInvalidXml() { + $this->config + ->expects($this->at(0)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue(0)); + $this->config + ->expects($this->at(1)) + ->method('setAppValue') + ->with('core', 'lastupdatedat', $this->isType('integer')); + $this->config + ->expects($this->at(3)) + ->method('getAppValue') + ->with('core', 'installedat') + ->will($this->returnValue('installedat')); + $this->config + ->expects($this->at(4)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue('lastupdatedat')); + $this->config + ->expects($this->at(5)) + ->method('setAppValue') + ->with('core', 'lastupdateResult', 'false'); + + $updateXml = 'Invalid XML Response!'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) + ->will($this->returnValue($updateXml)); + + $this->assertSame([], $this->updater->check()); + } + + public function testCheckWithUpdateUrl() { + $expectedResult = [ + 'version' => '8.0.4.2', + 'versionstring' => 'ownCloud 8.0.4', + 'url' => 'https://download.owncloud.org/community/owncloud-8.0.4.zip', + 'web' => 'http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html', + ]; + + $this->config + ->expects($this->at(0)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue(0)); + $this->config + ->expects($this->at(1)) + ->method('setAppValue') + ->with('core', 'lastupdatedat', $this->isType('integer')); + $this->config + ->expects($this->at(3)) + ->method('getAppValue') + ->with('core', 'installedat') + ->will($this->returnValue('installedat')); + $this->config + ->expects($this->at(4)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue('lastupdatedat')); + $this->config + ->expects($this->at(5)) + ->method('setAppValue') + ->with('core', 'lastupdateResult', json_encode($expectedResult)); + + $updateXml = '<?xml version="1.0"?> +<owncloud> + <version>8.0.4.2</version> + <versionstring>ownCloud 8.0.4</versionstring> + <url>https://download.owncloud.org/community/owncloud-8.0.4.zip</url> + <web>http://doc.owncloud.org/server/8.0/admin_manual/maintenance/upgrade.html</web> +</owncloud>'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://myupdater.com/')) + ->will($this->returnValue($updateXml)); + + $this->assertSame($expectedResult, $this->updater->check('https://myupdater.com/')); + } + + public function testCheckWithEmptyValidXmlResponse() { + $expectedResult = [ + 'version' => '', + 'versionstring' => '', + 'url' => '', + 'web' => '', + ]; + + $this->config + ->expects($this->at(0)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue(0)); + $this->config + ->expects($this->at(1)) + ->method('setAppValue') + ->with('core', 'lastupdatedat', $this->isType('integer')); + $this->config + ->expects($this->at(3)) + ->method('getAppValue') + ->with('core', 'installedat') + ->will($this->returnValue('installedat')); + $this->config + ->expects($this->at(4)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue('lastupdatedat')); + + $updateXml = '<?xml version="1.0"?> +<owncloud> + <version></version> + <versionstring></versionstring> + <url></url> + <web></web> +</owncloud>'; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) + ->will($this->returnValue($updateXml)); + + $this->assertSame($expectedResult, $this->updater->check()); + } + + public function testCheckWithEmptyInvalidXmlResponse() { + $expectedResult = []; + + $this->config + ->expects($this->at(0)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue(0)); + $this->config + ->expects($this->at(1)) + ->method('setAppValue') + ->with('core', 'lastupdatedat', $this->isType('integer')); + $this->config + ->expects($this->at(3)) + ->method('getAppValue') + ->with('core', 'installedat') + ->will($this->returnValue('installedat')); + $this->config + ->expects($this->at(4)) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->will($this->returnValue('lastupdatedat')); + $this->config + ->expects($this->at(5)) + ->method('setAppValue') + ->with('core', 'lastupdateResult', json_encode($expectedResult)); + + $updateXml = ''; + $this->updater + ->expects($this->once()) + ->method('getUrlContent') + ->with($this->buildUpdateUrl('https://updates.owncloud.com/server/')) + ->will($this->returnValue($updateXml)); + + $this->assertSame($expectedResult, $this->updater->check()); + } +} diff --git a/tests/phpunit-autotest-external.xml b/tests/phpunit-autotest-external.xml index 31d2e395a01..1b48c4dc11e 100644 --- a/tests/phpunit-autotest-external.xml +++ b/tests/phpunit-autotest-external.xml @@ -8,7 +8,7 @@ <testsuite name='ownCloud files external'> <directory suffix=".php">../apps/files_external/tests</directory> <!-- exclude backends as they are called separately --> - <exclude>../apps/files_external/tests/backends/</exclude> + <exclude>../apps/files_external/tests/storage/</exclude> </testsuite> <!-- filters for code coverage --> <filter> |