diff --git a/.github/workflows/phpunit-mysql-sharding.yml b/.github/workflows/phpunit-mysql-sharding.yml
index 9c02db9212654..96ba7a8c4feb5 100644
--- a/.github/workflows/phpunit-mysql-sharding.yml
+++ b/.github/workflows/phpunit-mysql-sharding.yml
@@ -57,9 +57,9 @@ jobs:
fail-fast: false
matrix:
include:
- - mysql-versions: '8.0'
- php-versions: '8.3'
- mysql-versions: '8.4'
+ php-versions: '8.3'
+ - mysql-versions: '9.7'
php-versions: '8.5'
name: Sharding - MySQL ${{ matrix.mysql-versions }} (PHP ${{ matrix.php-versions }}) - database tests
@@ -72,7 +72,7 @@ jobs:
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
mysql:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest # zizmor: ignore[unpinned-images]
+ image: mysql:${{ matrix.mysql-versions }} # zizmor: ignore[unpinned-images]
ports:
- 4444:3306/tcp
env:
@@ -82,7 +82,7 @@ jobs:
MYSQL_DATABASE: oc_autotest
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
shard1:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest # zizmor: ignore[unpinned-images]
+ image: mysql:${{ matrix.mysql-versions }} # zizmor: ignore[unpinned-images]
ports:
- 5001:3306/tcp
env:
@@ -92,7 +92,7 @@ jobs:
MYSQL_DATABASE: nextcloud
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
shard2:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest # zizmor: ignore[unpinned-images]
+ image: mysql:${{ matrix.mysql-versions }} # zizmor: ignore[unpinned-images]
ports:
- 5002:3306/tcp
env:
@@ -102,7 +102,7 @@ jobs:
MYSQL_DATABASE: nextcloud
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
shard3:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest # zizmor: ignore[unpinned-images]
+ image: mysql:${{ matrix.mysql-versions }} # zizmor: ignore[unpinned-images]
ports:
- 5003:3306/tcp
env:
@@ -112,7 +112,7 @@ jobs:
MYSQL_DATABASE: nextcloud
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 10
shard4:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest # zizmor: ignore[unpinned-images]
+ image: mysql:${{ matrix.mysql-versions }} # zizmor: ignore[unpinned-images]
ports:
- 5004:3306/tcp
env:
@@ -151,6 +151,13 @@ jobs:
echo "SET GLOBAL sql_mode=(SELECT CONCAT(@@sql_mode,',ONLY_FULL_GROUP_BY'));" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
echo "SELECT @@sql_mode;" | mysql -h 127.0.0.1 -P 4444 -u root -prootpassword
+ - name: Enable MD5 MySQL support
+ if: matrix.mysql-versions == '9.7'
+ run: |
+ for MYSQL_PORT in 4444 5001 5002 5003 5004; do
+ echo "INSTALL COMPONENT 'file://component_classic_hashing';" | mysql -h 127.0.0.1 -P $MYSQL_PORT -u root -prootpassword
+ done
+
- name: Set up Nextcloud
env:
DB_PORT: 4444
diff --git a/.github/workflows/phpunit-mysql.yml b/.github/workflows/phpunit-mysql.yml
index 55cf3b157133c..d31b8cc97bb08 100644
--- a/.github/workflows/phpunit-mysql.yml
+++ b/.github/workflows/phpunit-mysql.yml
@@ -60,9 +60,9 @@ jobs:
fail-fast: false
matrix:
include:
- - mysql-versions: '8.0'
- php-versions: '8.3'
- mysql-versions: '8.4'
+ php-versions: '8.3'
+ - mysql-versions: '9.7'
php-versions: '8.5'
name: MySQL ${{ matrix.mysql-versions }} (PHP ${{ matrix.php-versions }}) - database tests
@@ -75,7 +75,7 @@ jobs:
options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3
mysql:
- image: ghcr.io/nextcloud/continuous-integration-mysql-${{ matrix.mysql-versions }}:latest # zizmor: ignore[unpinned-images]
+ image: mysql:${{ matrix.mysql-versions }} # zizmor: ignore[unpinned-images]
ports:
- 4444:3306/tcp
env:
diff --git a/apps/settings/lib/SetupChecks/SupportedDatabase.php b/apps/settings/lib/SetupChecks/SupportedDatabase.php
index cf5c949c0ce9d..2edb26795e4a3 100644
--- a/apps/settings/lib/SetupChecks/SupportedDatabase.php
+++ b/apps/settings/lib/SetupChecks/SupportedDatabase.php
@@ -19,8 +19,8 @@ class SupportedDatabase implements ISetupCheck {
private const MIN_MARIADB = '10.6';
private const MAX_MARIADB = '11.8';
- private const MIN_MYSQL = '8.0';
- private const MAX_MYSQL = '8.4';
+ private const MIN_MYSQL = '8.4';
+ private const MAX_MYSQL = '9.7';
private const MIN_POSTGRES = '14';
private const MAX_POSTGRES = '18';
private const MIN_ORACLE = '12.2';
diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index 3abce0fbe43bb..329f3732fb029 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -1420,6 +1420,11 @@
+
+
+
+
+
@@ -3232,6 +3237,11 @@
request->server]]>
+
+
+
+
+
diff --git a/lib/private/Setup/MySQL.php b/lib/private/Setup/MySQL.php
index 492d83d3cd271..b2b468d699929 100644
--- a/lib/private/Setup/MySQL.php
+++ b/lib/private/Setup/MySQL.php
@@ -8,7 +8,6 @@
namespace OC\Setup;
-use Doctrine\DBAL\Platforms\MySQL80Platform;
use Doctrine\DBAL\Platforms\MySQL84Platform;
use OC\DatabaseSetupException;
use OC\DB\ConnectionAdapter;
@@ -39,6 +38,28 @@ public function setupDatabase(): void {
'dbpassword' => $this->dbPassword,
]);
+ // for MD5 support
+ // In MySQL 9+ MD5 has been deprecated and is only available as a component.
+ // Until we dropped the support for it on the function builder, we need to load the component.
+ if ($connection->getDatabasePlatform() instanceof MySQL84Platform) {
+ $statement = $connection->prepare("SHOW VARIABLES LIKE 'version';");
+ $result = $statement->executeQuery();
+ $row = $result->fetchAssociative();
+ $version = $row['Value'];
+ [$major, ] = explode('.', strtolower($version));
+ if ((int)$major >= 9) {
+ // check if the component is already loaded, if not load it
+ $statement = $connection->prepare("SELECT COUNT(*) FROM mysql.component WHERE component_urn = 'file://component_classic_hashing';");
+ $result = $statement->executeQuery();
+ $count = $result->fetchOne();
+ if ($count !== false && (int)$count === 0) {
+ // not yet loaded
+ $statement = $connection->prepare("INSTALL COMPONENT 'file://component_classic_hashing';");
+ $statement->executeStatement();
+ }
+ }
+ }
+
//create the database
$this->createDatabase($connection);
@@ -103,12 +124,6 @@ private function createDBUser(IDBConnection $connection): void {
$connection->executeStatement($query, [$name,$password]);
$query = "CREATE USER ?@'%' IDENTIFIED WITH caching_sha2_password BY ?";
$connection->executeStatement($query, [$name,$password]);
- } elseif ($connection->getDatabasePlatform() instanceof Mysql80Platform) {
- // TODO: Remove this elseif section as soon as MySQL 8.0 is out-of-support (after April 2026)
- $query = "CREATE USER ?@'localhost' IDENTIFIED WITH mysql_native_password BY ?";
- $connection->executeStatement($query, [$name,$password]);
- $query = "CREATE USER ?@'%' IDENTIFIED WITH mysql_native_password BY ?";
- $connection->executeStatement($query, [$name,$password]);
} else {
$query = "CREATE USER ?@'localhost' IDENTIFIED BY ?";
$connection->executeStatement($query, [$name,$password]);
diff --git a/lib/public/DB/QueryBuilder/IFunctionBuilder.php b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
index 2667f1487969a..f792e05cf6046 100644
--- a/lib/public/DB/QueryBuilder/IFunctionBuilder.php
+++ b/lib/public/DB/QueryBuilder/IFunctionBuilder.php
@@ -20,6 +20,7 @@ interface IFunctionBuilder {
*
* @return IQueryFunction
* @since 12.0.0
+ * @deprecated 35.0.0 - MD5 is not considered secure anymore, thus most databases have or will drop support for this function
*/
public function md5($input): IQueryFunction;