diff options
51 files changed, 233 insertions, 62 deletions
@@ -29,4 +29,4 @@ OC.L10N.register( "Quota" : "Límite", "Advanced Permissions" : "Permisos avanzados" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es.json b/l10n/es.json index 439338f3..adcc8664 100644 --- a/l10n/es.json +++ b/l10n/es.json @@ -26,5 +26,5 @@ "Groups" : "Grupos", "Quota" : "Límite", "Advanced Permissions" : "Permisos avanzados" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_419.js b/l10n/es_419.js index af702bb3..495c3012 100644 --- a/l10n/es_419.js +++ b/l10n/es_419.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_419.json b/l10n/es_419.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_419.json +++ b/l10n/es_419.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_AR.js b/l10n/es_AR.js index bf737e07..9682ae0b 100644 --- a/l10n/es_AR.js +++ b/l10n/es_AR.js @@ -15,4 +15,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_AR.json b/l10n/es_AR.json index 6481f52c..b3e40fb7 100644 --- a/l10n/es_AR.json +++ b/l10n/es_AR.json @@ -12,5 +12,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_CL.js b/l10n/es_CL.js index fc8aa8b8..f3d123b3 100644 --- a/l10n/es_CL.js +++ b/l10n/es_CL.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_CL.json b/l10n/es_CL.json index cd0f9df2..9e6ae91e 100644 --- a/l10n/es_CL.json +++ b/l10n/es_CL.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_CO.js b/l10n/es_CO.js index fc8aa8b8..f3d123b3 100644 --- a/l10n/es_CO.js +++ b/l10n/es_CO.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_CO.json b/l10n/es_CO.json index cd0f9df2..9e6ae91e 100644 --- a/l10n/es_CO.json +++ b/l10n/es_CO.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_CR.js b/l10n/es_CR.js index fc8aa8b8..f3d123b3 100644 --- a/l10n/es_CR.js +++ b/l10n/es_CR.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_CR.json b/l10n/es_CR.json index cd0f9df2..9e6ae91e 100644 --- a/l10n/es_CR.json +++ b/l10n/es_CR.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_DO.js b/l10n/es_DO.js index fc8aa8b8..f3d123b3 100644 --- a/l10n/es_DO.js +++ b/l10n/es_DO.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_DO.json b/l10n/es_DO.json index cd0f9df2..9e6ae91e 100644 --- a/l10n/es_DO.json +++ b/l10n/es_DO.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_EC.js b/l10n/es_EC.js index fc8aa8b8..f3d123b3 100644 --- a/l10n/es_EC.js +++ b/l10n/es_EC.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_EC.json b/l10n/es_EC.json index cd0f9df2..9e6ae91e 100644 --- a/l10n/es_EC.json +++ b/l10n/es_EC.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_GT.js b/l10n/es_GT.js index fc8aa8b8..f3d123b3 100644 --- a/l10n/es_GT.js +++ b/l10n/es_GT.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_GT.json b/l10n/es_GT.json index cd0f9df2..9e6ae91e 100644 --- a/l10n/es_GT.json +++ b/l10n/es_GT.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_HN.js b/l10n/es_HN.js index af702bb3..495c3012 100644 --- a/l10n/es_HN.js +++ b/l10n/es_HN.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_HN.json b/l10n/es_HN.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_HN.json +++ b/l10n/es_HN.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_MX.js b/l10n/es_MX.js index c06662a4..1da58a10 100644 --- a/l10n/es_MX.js +++ b/l10n/es_MX.js @@ -16,4 +16,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_MX.json b/l10n/es_MX.json index d4a77af7..2cf55709 100644 --- a/l10n/es_MX.json +++ b/l10n/es_MX.json @@ -13,5 +13,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_NI.js b/l10n/es_NI.js index af702bb3..495c3012 100644 --- a/l10n/es_NI.js +++ b/l10n/es_NI.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_NI.json b/l10n/es_NI.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_NI.json +++ b/l10n/es_NI.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_PA.js b/l10n/es_PA.js index af702bb3..495c3012 100644 --- a/l10n/es_PA.js +++ b/l10n/es_PA.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_PA.json b/l10n/es_PA.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_PA.json +++ b/l10n/es_PA.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_PE.js b/l10n/es_PE.js index af702bb3..495c3012 100644 --- a/l10n/es_PE.js +++ b/l10n/es_PE.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_PE.json b/l10n/es_PE.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_PE.json +++ b/l10n/es_PE.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_PR.js b/l10n/es_PR.js index af702bb3..495c3012 100644 --- a/l10n/es_PR.js +++ b/l10n/es_PR.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_PR.json b/l10n/es_PR.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_PR.json +++ b/l10n/es_PR.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_PY.js b/l10n/es_PY.js index af702bb3..495c3012 100644 --- a/l10n/es_PY.js +++ b/l10n/es_PY.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_PY.json b/l10n/es_PY.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_PY.json +++ b/l10n/es_PY.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_SV.js b/l10n/es_SV.js index fc8aa8b8..0328638d 100644 --- a/l10n/es_SV.js +++ b/l10n/es_SV.js @@ -14,4 +14,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=2; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_SV.json b/l10n/es_SV.json index cd0f9df2..9ed212b3 100644 --- a/l10n/es_SV.json +++ b/l10n/es_SV.json @@ -11,5 +11,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=2; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/es_UY.js b/l10n/es_UY.js index af702bb3..495c3012 100644 --- a/l10n/es_UY.js +++ b/l10n/es_UY.js @@ -13,4 +13,4 @@ OC.L10N.register( "Groups" : "Grupos", "Quota" : "Cuota" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/es_UY.json b/l10n/es_UY.json index 4cf432c9..fad96c91 100644 --- a/l10n/es_UY.json +++ b/l10n/es_UY.json @@ -10,5 +10,5 @@ "Folder name" : "Nombre de la carpeta", "Groups" : "Grupos", "Quota" : "Cuota" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file @@ -29,4 +29,4 @@ OC.L10N.register( "Quota" : "Quota", "Advanced Permissions" : "Autorisations avancées" }, -"nplurals=2; plural=(n > 1);"); +"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/fr.json b/l10n/fr.json index 16d757f3..1d581f10 100644 --- a/l10n/fr.json +++ b/l10n/fr.json @@ -26,5 +26,5 @@ "Groups" : "Groupes", "Quota" : "Quota", "Advanced Permissions" : "Autorisations avancées" -},"pluralForm" :"nplurals=2; plural=(n > 1);" +},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file @@ -29,4 +29,4 @@ OC.L10N.register( "Quota" : "Quota", "Advanced Permissions" : "Autorizzazioni avanzate" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/it.json b/l10n/it.json index b08d394f..e2caeb8a 100644 --- a/l10n/it.json +++ b/l10n/it.json @@ -26,5 +26,5 @@ "Groups" : "Gruppi", "Quota" : "Quota", "Advanced Permissions" : "Autorizzazioni avanzate" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/pt_BR.js b/l10n/pt_BR.js index 2faa3092..07233a35 100644 --- a/l10n/pt_BR.js +++ b/l10n/pt_BR.js @@ -29,4 +29,4 @@ OC.L10N.register( "Quota" : "Cota", "Advanced Permissions" : "Permissões avançadas" }, -"nplurals=2; plural=(n > 1);"); +"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/pt_BR.json b/l10n/pt_BR.json index 835f5828..0a8715a4 100644 --- a/l10n/pt_BR.json +++ b/l10n/pt_BR.json @@ -26,5 +26,5 @@ "Groups" : "Grupos", "Quota" : "Cota", "Advanced Permissions" : "Permissões avançadas" -},"pluralForm" :"nplurals=2; plural=(n > 1);" +},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/l10n/pt_PT.js b/l10n/pt_PT.js index 91835750..527c773f 100644 --- a/l10n/pt_PT.js +++ b/l10n/pt_PT.js @@ -25,4 +25,4 @@ OC.L10N.register( "Quota" : "Quota", "Advanced Permissions" : "Permissões avançadas" }, -"nplurals=2; plural=(n != 1);"); +"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); diff --git a/l10n/pt_PT.json b/l10n/pt_PT.json index 027fb862..e357571b 100644 --- a/l10n/pt_PT.json +++ b/l10n/pt_PT.json @@ -22,5 +22,5 @@ "Groups" : "Grupos", "Quota" : "Quota", "Advanced Permissions" : "Permissões avançadas" -},"pluralForm" :"nplurals=2; plural=(n != 1);" +},"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" }
\ No newline at end of file diff --git a/lib/ACL/Rule.php b/lib/ACL/Rule.php index 6269a92f..c630a6da 100644 --- a/lib/ACL/Rule.php +++ b/lib/ACL/Rule.php @@ -98,6 +98,7 @@ class Rule implements XmlSerializable, XmlDeserializable, \JsonSerializable { $writer->write($data); } + #[\ReturnTypeWillChange] public function jsonSerialize() { return [ 'mapping' => [ diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 6d2ea82e..890ea3e2 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -76,6 +76,8 @@ class Application extends App implements IBootstrap { $rootProvider = function () use ($c): LazyFolder { return $c->get('GroupAppFolder'); }; + $config = $c->get(IConfig::class); + $allowRootShare = $config->getAppValue('groupfolders', 'allow_root_share', 'true') === 'true'; return new MountProvider( $c->getServer()->getGroupManager(), @@ -87,7 +89,8 @@ class Application extends App implements IBootstrap { $c->get(ISession::class), $c->get(IMountProviderCollection::class), $c->get(IDBConnection::class), - $c->get(ICacheFactory::class)->createLocal("groupfolders") + $c->get(ICacheFactory::class)->createLocal("groupfolders"), + $allowRootShare ); }); diff --git a/lib/Mount/CacheRootPermissionsMask.php b/lib/Mount/CacheRootPermissionsMask.php new file mode 100644 index 00000000..2c0b83b6 --- /dev/null +++ b/lib/Mount/CacheRootPermissionsMask.php @@ -0,0 +1,46 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\GroupFolders\Mount; + +use OC\Files\Cache\Wrapper\CacheWrapper; +use OCP\Files\Cache\ICache; + +class CacheRootPermissionsMask extends CacheWrapper { + protected int $mask; + + public function __construct(ICache $cache, int $mask) { + parent::__construct($cache); + $this->mask = $mask; + } + + protected function formatCacheEntry($entry) { + $path = $entry['path']; + $isRoot = $path === '' || (strpos($path, '__groupfolders') === 0 && count(explode('/', $path)) === 2); + if (isset($entry['permissions']) && $isRoot) { + $entry['scan_permissions'] = $entry['permissions']; + $entry['permissions'] &= $this->mask; + } + return $entry; + } +} diff --git a/lib/Mount/MountProvider.php b/lib/Mount/MountProvider.php index 3dc01adc..9f5c09dd 100644 --- a/lib/Mount/MountProvider.php +++ b/lib/Mount/MountProvider.php @@ -26,6 +26,7 @@ use OC\Files\Storage\Wrapper\PermissionsMask; use OCA\GroupFolders\ACL\ACLManagerFactory; use OCA\GroupFolders\ACL\ACLStorageWrapper; use OCA\GroupFolders\Folder\FolderManager; +use OCP\Constants; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Config\IMountProvider; use OCP\Files\Config\IMountProviderCollection; @@ -69,6 +70,7 @@ class MountProvider implements IMountProvider { private $connection; private ICache $cache; private ?int $rootStorageId = null; + private bool $allowRootShare; public function __construct( IGroupManager $groupProvider, @@ -80,7 +82,8 @@ class MountProvider implements IMountProvider { ISession $session, IMountProviderCollection $mountProviderCollection, IDBConnection $connection, - ICache $cache + ICache $cache, + bool $allowRootShare ) { $this->groupProvider = $groupProvider; $this->folderManager = $folderManager; @@ -92,6 +95,7 @@ class MountProvider implements IMountProvider { $this->mountProviderCollection = $mountProviderCollection; $this->connection = $connection; $this->cache = $cache; + $this->allowRootShare = $allowRootShare; } private function getRootStorageId(): int { @@ -217,6 +221,13 @@ class MountProvider implements IMountProvider { 'mask' => $permissions ]); + if (!$this->allowRootShare) { + $maskedStore = new RootPermissionsMask([ + 'storage' => $maskedStore, + 'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE, + ]); + } + return new GroupMountPoint( $id, $maskedStore, diff --git a/lib/Mount/RootPermissionsMask.php b/lib/Mount/RootPermissionsMask.php new file mode 100644 index 00000000..6f5a9fe6 --- /dev/null +++ b/lib/Mount/RootPermissionsMask.php @@ -0,0 +1,110 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +namespace OCA\GroupFolders\Mount; + +use OC\Files\Storage\Wrapper\Wrapper; +use OCP\Constants; + +/** + * Permissions mask that only masks the root of the storage + */ +class RootPermissionsMask extends Wrapper { + /** + * @var int the permissions bits we want to keep + */ + private $mask; + + /** + * @param array $arguments ['storage' => $storage, 'mask' => $mask] + * + * $storage: The storage the permissions mask should be applied on + * $mask: The permission bits that should be kept, a combination of the \OCP\Constant::PERMISSION_ constants + */ + public function __construct($arguments) { + parent::__construct($arguments); + $this->mask = $arguments['mask']; + } + + private function checkMask($permissions) { + return ($this->mask & $permissions) === $permissions; + } + + public function isUpdatable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_UPDATE) and parent::isUpdatable($path); + } else { + return parent::isUpdatable($path); + } + } + + public function isCreatable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_CREATE) and parent::isCreatable($path); + } else { + return parent::isCreatable($path); + } + } + + public function isDeletable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_DELETE) and parent::isDeletable($path); + } else { + return parent::isDeletable($path); + } + } + + public function isSharable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_SHARE) and parent::isSharable($path); + } else { + return parent::isSharable($path); + } + } + + public function getPermissions($path) { + if ($path === '') { + return $this->storage->getPermissions($path) & $this->mask; + } else { + return $this->storage->getPermissions($path); + } + } + + public function getMetaData($path) { + $data = parent::getMetaData($path); + + if ($data && $path === '' && isset($data['permissions'])) { + $data['scan_permissions'] = $data['scan_permissions'] ?? $data['permissions']; + $data['permissions'] &= $this->mask; + } + return $data; + } + + public function getCache($path = '', $storage = null) { + if (!$storage) { + $storage = $this; + } + $sourceCache = parent::getCache($path, $storage); + return new CacheRootPermissionsMask($sourceCache, $this->mask); + } +} diff --git a/package-lock.json b/package-lock.json index 64ad9190..09f583c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,12 +30,12 @@ "@types/react": "^17.0.43", "@types/react-dom": "^18.0.3", "@types/webpack": "^4.41.26", - "@types/webpack-env": "^1.16.4", + "@types/webpack-env": "^1.17.0", "clean-webpack-plugin": "^4.0.0", "eslint-plugin-react": "^7.30.0", "react-hot-loader": "4.13.0", "ts-loader": "^9.3.0", - "typescript": "^4.6.4" + "typescript": "^4.7.3" }, "engines": { "node": "^14.0.0", @@ -2725,9 +2725,9 @@ } }, "node_modules/@types/webpack-env": { - "version": "1.16.4", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.4.tgz", - "integrity": "sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.17.0.tgz", + "integrity": "sha512-eHSaNYEyxRA5IAG0Ym/yCyf86niZUIF/TpWKofQI/CVfh5HsMEUyfE2kwFxha4ow0s5g0LfISQxpDKjbRDrizw==", "dev": true }, "node_modules/@types/webpack-sources": { @@ -11949,9 +11949,9 @@ } }, "node_modules/typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -15252,9 +15252,9 @@ } }, "@types/webpack-env": { - "version": "1.16.4", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.4.tgz", - "integrity": "sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.17.0.tgz", + "integrity": "sha512-eHSaNYEyxRA5IAG0Ym/yCyf86niZUIF/TpWKofQI/CVfh5HsMEUyfE2kwFxha4ow0s5g0LfISQxpDKjbRDrizw==", "dev": true }, "@types/webpack-sources": { @@ -22517,9 +22517,9 @@ } }, "typescript": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", - "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 40cfba3c..a744fa4c 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,12 @@ "@types/react": "^17.0.43", "@types/react-dom": "^18.0.3", "@types/webpack": "^4.41.26", - "@types/webpack-env": "^1.16.4", + "@types/webpack-env": "^1.17.0", "clean-webpack-plugin": "^4.0.0", "eslint-plugin-react": "^7.30.0", "react-hot-loader": "4.13.0", "ts-loader": "^9.3.0", - "typescript": "^4.6.4" + "typescript": "^4.7.3" }, "dependencies": { "@nextcloud/axios": "^1.10.0", |