summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/lib/Server.php3
-rw-r--r--apps/federation/l10n/fr.js4
-rw-r--r--apps/federation/l10n/fr.json4
-rw-r--r--apps/federation/l10n/is.js12
-rw-r--r--apps/federation/l10n/is.json12
-rw-r--r--apps/files/l10n/fr.js1
-rw-r--r--apps/files/l10n/fr.json1
-rw-r--r--apps/files/l10n/is.js3
-rw-r--r--apps/files/l10n/is.json3
-rw-r--r--apps/files_external/l10n/is.js7
-rw-r--r--apps/files_external/l10n/is.json7
-rw-r--r--apps/files_external/l10n/pt_BR.js2
-rw-r--r--apps/files_external/l10n/pt_BR.json2
-rw-r--r--apps/files_sharing/css/public.css9
-rw-r--r--apps/files_sharing/l10n/is.js8
-rw-r--r--apps/files_sharing/l10n/is.json8
-rw-r--r--apps/systemtags/admin.php23
-rw-r--r--apps/systemtags/appinfo/app.php3
-rw-r--r--apps/systemtags/appinfo/info.xml2
-rw-r--r--apps/systemtags/js/admin.js164
-rw-r--r--apps/systemtags/l10n/ca.js2
-rw-r--r--apps/systemtags/l10n/ca.json2
-rw-r--r--apps/systemtags/l10n/cs_CZ.js2
-rw-r--r--apps/systemtags/l10n/cs_CZ.json2
-rw-r--r--apps/systemtags/l10n/de.js2
-rw-r--r--apps/systemtags/l10n/de.json2
-rw-r--r--apps/systemtags/l10n/de_DE.js2
-rw-r--r--apps/systemtags/l10n/de_DE.json2
-rw-r--r--apps/systemtags/l10n/en_GB.js2
-rw-r--r--apps/systemtags/l10n/en_GB.json2
-rw-r--r--apps/systemtags/l10n/es.js2
-rw-r--r--apps/systemtags/l10n/es.json2
-rw-r--r--apps/systemtags/l10n/fr.js2
-rw-r--r--apps/systemtags/l10n/fr.json2
-rw-r--r--apps/systemtags/l10n/he.js2
-rw-r--r--apps/systemtags/l10n/he.json2
-rw-r--r--apps/systemtags/l10n/hu_HU.js2
-rw-r--r--apps/systemtags/l10n/hu_HU.json2
-rw-r--r--apps/systemtags/l10n/is.js10
-rw-r--r--apps/systemtags/l10n/is.json10
-rw-r--r--apps/systemtags/l10n/it.js2
-rw-r--r--apps/systemtags/l10n/it.json2
-rw-r--r--apps/systemtags/l10n/ja.js2
-rw-r--r--apps/systemtags/l10n/ja.json2
-rw-r--r--apps/systemtags/l10n/nl.js2
-rw-r--r--apps/systemtags/l10n/nl.json2
-rw-r--r--apps/systemtags/l10n/pt_BR.js2
-rw-r--r--apps/systemtags/l10n/pt_BR.json2
-rw-r--r--apps/systemtags/l10n/pt_PT.js2
-rw-r--r--apps/systemtags/l10n/pt_PT.json2
-rw-r--r--apps/systemtags/l10n/ro.js2
-rw-r--r--apps/systemtags/l10n/ro.json2
-rw-r--r--apps/systemtags/l10n/ru.js2
-rw-r--r--apps/systemtags/l10n/ru.json2
-rw-r--r--apps/systemtags/l10n/sl.js2
-rw-r--r--apps/systemtags/l10n/sl.json2
-rw-r--r--apps/systemtags/l10n/sq.js2
-rw-r--r--apps/systemtags/l10n/sq.json2
-rw-r--r--apps/systemtags/l10n/sv.js2
-rw-r--r--apps/systemtags/l10n/sv.json2
-rw-r--r--apps/systemtags/lib/AppInfo/Application.php37
-rw-r--r--apps/systemtags/templates/admin.php59
-rw-r--r--apps/theming/appinfo/app.php2
-rw-r--r--apps/theming/appinfo/routes.php6
-rw-r--r--apps/theming/js/settings-admin.js27
-rw-r--r--apps/theming/lib/Controller/ThemingController.php (renamed from apps/theming/lib/controller/themingcontroller.php)93
-rw-r--r--apps/theming/lib/Template.php (renamed from apps/theming/lib/template.php)2
-rw-r--r--apps/theming/lib/Util.php (renamed from apps/theming/lib/util.php)31
-rw-r--r--apps/theming/settings/settings-admin.php4
-rw-r--r--apps/theming/tests/Controller/ThemingControllerTest.php (renamed from apps/theming/tests/lib/controller/ThemingControllerTest.php)245
-rw-r--r--apps/theming/tests/TemplateTest.php (renamed from apps/theming/tests/lib/TemplateTest.php)0
-rw-r--r--apps/theming/tests/UtilTest.php97
-rw-r--r--apps/theming/tests/lib/UtilTest.php68
-rw-r--r--apps/updatenotification/l10n/is.js6
-rw-r--r--apps/updatenotification/l10n/is.json6
-rw-r--r--apps/user_ldap/ajax/wizard.php2
-rw-r--r--apps/user_ldap/appinfo/app.php2
-rw-r--r--apps/user_ldap/appinfo/install.php4
-rw-r--r--apps/user_ldap/appinfo/update.php24
-rw-r--r--apps/user_ldap/lib/Access.php73
-rw-r--r--apps/user_ldap/lib/Connection.php6
-rw-r--r--apps/user_ldap/lib/Helper.php65
-rw-r--r--apps/user_ldap/lib/IUserLDAP.php49
-rw-r--r--apps/user_ldap/lib/Jobs/UpdateGroups.php2
-rw-r--r--apps/user_ldap/lib/LDAPProvider.php188
-rw-r--r--apps/user_ldap/lib/LDAPProviderFactory.php59
-rw-r--r--apps/user_ldap/lib/Proxy.php2
-rw-r--r--apps/user_ldap/lib/User/User.php5
-rw-r--r--apps/user_ldap/lib/User_LDAP.php45
-rw-r--r--apps/user_ldap/lib/User_Proxy.php32
-rw-r--r--apps/user_ldap/tests/AccessTest.php51
-rw-r--r--apps/user_ldap/tests/Group_LDAPTest.php3
-rw-r--r--apps/user_ldap/tests/Integration/AbstractIntegrationTest.php14
-rw-r--r--apps/user_ldap/tests/LDAPProviderTest.php338
-rw-r--r--apps/user_ldap/tests/User/UserTest.php3
-rw-r--r--apps/user_ldap/tests/User_LDAPTest.php4
-rw-r--r--apps/user_ldap/tests/WizardTest.php3
-rw-r--r--apps/workflowengine/lib/Check/UserGroupMembership.php12
-rw-r--r--apps/workflowengine/lib/Manager.php14
-rw-r--r--apps/workflowengine/templates/admin.php14
100 files changed, 1746 insertions, 325 deletions
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index e80f9ae125a..9058548489c 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -173,6 +173,9 @@ class Server {
)
)
);
+ $this->server->addPlugin(
+ new \OCA\DAV\Connector\Sabre\QuotaPlugin($view));
+
}
});
}
diff --git a/apps/federation/l10n/fr.js b/apps/federation/l10n/fr.js
index 95029368394..9113e44017b 100644
--- a/apps/federation/l10n/fr.js
+++ b/apps/federation/l10n/fr.js
@@ -8,6 +8,8 @@ OC.L10N.register(
"Federation" : "Fédération",
"Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La « fédération » vous permet de vous connecter avec d'autres serveurs de confiance pour échanger la liste des utilisateurs. Par exemple, ce sera utilisé pour auto-compléter les utilisateurs externes lors du partage fédéré.",
"Add server automatically once a federated share was created successfully" : "Ajouter un serveur automatiquement une fois que le partage a été créé avec succès .",
- "Trusted Servers" : "Serveurs de confiance"
+ "Trusted Servers" : "Serveurs de confiance",
+ "+ Add Nextcloud server" : "+ Ajouter un serveur Nextcloud",
+ "Nextcloud Server" : "Serveur Nextcloud"
},
"nplurals=2; plural=(n > 1);");
diff --git a/apps/federation/l10n/fr.json b/apps/federation/l10n/fr.json
index 57487dec6d8..88667336936 100644
--- a/apps/federation/l10n/fr.json
+++ b/apps/federation/l10n/fr.json
@@ -6,6 +6,8 @@
"Federation" : "Fédération",
"Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "La « fédération » vous permet de vous connecter avec d'autres serveurs de confiance pour échanger la liste des utilisateurs. Par exemple, ce sera utilisé pour auto-compléter les utilisateurs externes lors du partage fédéré.",
"Add server automatically once a federated share was created successfully" : "Ajouter un serveur automatiquement une fois que le partage a été créé avec succès .",
- "Trusted Servers" : "Serveurs de confiance"
+ "Trusted Servers" : "Serveurs de confiance",
+ "+ Add Nextcloud server" : "+ Ajouter un serveur Nextcloud",
+ "Nextcloud Server" : "Serveur Nextcloud"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
} \ No newline at end of file
diff --git a/apps/federation/l10n/is.js b/apps/federation/l10n/is.js
index 970656835fd..e7016e9b154 100644
--- a/apps/federation/l10n/is.js
+++ b/apps/federation/l10n/is.js
@@ -1,15 +1,15 @@
OC.L10N.register(
"federation",
{
- "Server added to the list of trusted ownClouds" : "Þjóninum bætt við listann yfir treyst ownCloud-ský",
+ "Added to the list of trusted servers" : "Bætt á lista yfir treysta þjóna",
"Server is already in the list of trusted servers." : "Þjónninn er nú þegar á listanum yfir treysta þjóna.",
- "No ownCloud server found" : "Enginn ownCloud-þjónn fannst",
+ "No server to federate found" : "Enginn sambandsþjónn fannst",
"Could not add server" : "Gat ekki bætt við þjóni",
"Federation" : "Samband",
- "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud-samband (federation) gerir þér kleift að tengjast öðrumtreystum ownCloud-skýjum til að skiptast á notendaskrám. Þetta er til dæmis notað til að sjálfklára nöfn ytri notenda við deilingu sambandssameigna.",
+ "Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Þjónasamband (federation) gerir þér kleift að tengjast öðrumtreystum skýjum til að skiptast á notendaskrám. Þetta er til dæmis notað til að sjálfklára nöfn ytri notenda við deilingu sambandssameigna.",
"Add server automatically once a federated share was created successfully" : "Bæta þjóni við sjálfkrafa, hafi tekist að búa til sambandssameign",
- "Trusted ownCloud Servers" : "Treystir ownCloud-þjónar",
- "+ Add ownCloud server" : "+ Bæta við ownCloud-þjóni",
- "ownCloud Server" : "ownCloud-þjónn"
+ "Trusted Servers" : "Treystir þjónar",
+ "+ Add Nextcloud server" : "+ Bæta við Nextcloud þjóni",
+ "Nextcloud Server" : "Nextcloud þjónn"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/federation/l10n/is.json b/apps/federation/l10n/is.json
index 3754dc12ed7..4f61cb1258b 100644
--- a/apps/federation/l10n/is.json
+++ b/apps/federation/l10n/is.json
@@ -1,13 +1,13 @@
{ "translations": {
- "Server added to the list of trusted ownClouds" : "Þjóninum bætt við listann yfir treyst ownCloud-ský",
+ "Added to the list of trusted servers" : "Bætt á lista yfir treysta þjóna",
"Server is already in the list of trusted servers." : "Þjónninn er nú þegar á listanum yfir treysta þjóna.",
- "No ownCloud server found" : "Enginn ownCloud-þjónn fannst",
+ "No server to federate found" : "Enginn sambandsþjónn fannst",
"Could not add server" : "Gat ekki bætt við þjóni",
"Federation" : "Samband",
- "ownCloud Federation allows you to connect with other trusted ownClouds to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "ownCloud-samband (federation) gerir þér kleift að tengjast öðrumtreystum ownCloud-skýjum til að skiptast á notendaskrám. Þetta er til dæmis notað til að sjálfklára nöfn ytri notenda við deilingu sambandssameigna.",
+ "Federation allows you to connect with other trusted servers to exchange the user directory. For example this will be used to auto-complete external users for federated sharing." : "Þjónasamband (federation) gerir þér kleift að tengjast öðrumtreystum skýjum til að skiptast á notendaskrám. Þetta er til dæmis notað til að sjálfklára nöfn ytri notenda við deilingu sambandssameigna.",
"Add server automatically once a federated share was created successfully" : "Bæta þjóni við sjálfkrafa, hafi tekist að búa til sambandssameign",
- "Trusted ownCloud Servers" : "Treystir ownCloud-þjónar",
- "+ Add ownCloud server" : "+ Bæta við ownCloud-þjóni",
- "ownCloud Server" : "ownCloud-þjónn"
+ "Trusted Servers" : "Treystir þjónar",
+ "+ Add Nextcloud server" : "+ Bæta við Nextcloud þjóni",
+ "Nextcloud Server" : "Nextcloud þjónn"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/apps/files/l10n/fr.js b/apps/files/l10n/fr.js
index 49f5204c977..cd725b01164 100644
--- a/apps/files/l10n/fr.js
+++ b/apps/files/l10n/fr.js
@@ -21,6 +21,7 @@ OC.L10N.register(
"Invalid directory." : "Dossier non valide.",
"Files" : "Fichiers",
"All files" : "Tous les fichiers",
+ "Recent" : "Récent",
"File could not be found" : "Ce fichier n'a pu être trouvé.",
"Home" : "Mes fichiers",
"Close" : "Fermer",
diff --git a/apps/files/l10n/fr.json b/apps/files/l10n/fr.json
index e0b5dba2186..60c7a374bd8 100644
--- a/apps/files/l10n/fr.json
+++ b/apps/files/l10n/fr.json
@@ -19,6 +19,7 @@
"Invalid directory." : "Dossier non valide.",
"Files" : "Fichiers",
"All files" : "Tous les fichiers",
+ "Recent" : "Récent",
"File could not be found" : "Ce fichier n'a pu être trouvé.",
"Home" : "Mes fichiers",
"Close" : "Fermer",
diff --git a/apps/files/l10n/is.js b/apps/files/l10n/is.js
index 579ac88f97f..989dc468f0c 100644
--- a/apps/files/l10n/is.js
+++ b/apps/files/l10n/is.js
@@ -21,6 +21,8 @@ OC.L10N.register(
"Invalid directory." : "Ógild mappa.",
"Files" : "Skrár",
"All files" : "Allar skrár",
+ "Recent" : "Nýlegt",
+ "File could not be found" : "Skrá finnst ekki",
"Home" : "Heim",
"Close" : "Loka",
"Favorites" : "Eftirlæti",
@@ -82,6 +84,7 @@ OC.L10N.register(
"Storage of {owner} is almost full ({usedSpacePercent}%)" : "Geymslupláss {owner} er næstum fullt ({usedSpacePercent}%)",
"Your storage is almost full ({usedSpacePercent}%)" : "Geymsluplássið þitt er næstum fullt ({usedSpacePercent}%)",
"_matches '{filter}'_::_match '{filter}'_" : ["samsvarar '{filter}'","samsvara '{filter}'"],
+ "View in folder" : "Skoða í möppu",
"Path" : "Slóð",
"_%n byte_::_%n bytes_" : ["%n bæti","%n bæti"],
"Favorited" : "Sett í eftirlæti",
diff --git a/apps/files/l10n/is.json b/apps/files/l10n/is.json
index 2b4f980ca6d..65da27622f8 100644
--- a/apps/files/l10n/is.json
+++ b/apps/files/l10n/is.json
@@ -19,6 +19,8 @@
"Invalid directory." : "Ógild mappa.",
"Files" : "Skrár",
"All files" : "Allar skrár",
+ "Recent" : "Nýlegt",
+ "File could not be found" : "Skrá finnst ekki",
"Home" : "Heim",
"Close" : "Loka",
"Favorites" : "Eftirlæti",
@@ -80,6 +82,7 @@
"Storage of {owner} is almost full ({usedSpacePercent}%)" : "Geymslupláss {owner} er næstum fullt ({usedSpacePercent}%)",
"Your storage is almost full ({usedSpacePercent}%)" : "Geymsluplássið þitt er næstum fullt ({usedSpacePercent}%)",
"_matches '{filter}'_::_match '{filter}'_" : ["samsvarar '{filter}'","samsvara '{filter}'"],
+ "View in folder" : "Skoða í möppu",
"Path" : "Slóð",
"_%n byte_::_%n bytes_" : ["%n bæti","%n bæti"],
"Favorited" : "Sett í eftirlæti",
diff --git a/apps/files_external/l10n/is.js b/apps/files_external/l10n/is.js
index 80d39a2ba9a..ab73dbece96 100644
--- a/apps/files_external/l10n/is.js
+++ b/apps/files_external/l10n/is.js
@@ -7,6 +7,8 @@ OC.L10N.register(
"Step 1 failed. Exception: %s" : "Skref 1 mistókst. Undantekning: %s",
"Step 2 failed. Exception: %s" : "Skref 2 mistókst. Undantekning: %s",
"External storage" : "Ytri gagnageymsla",
+ "Dropbox App Configuration" : "Uppsetning Dropbox forrits",
+ "Google Drive App Configuration" : "Uppsetning Google Drive forrits",
"Personal" : "Einka",
"System" : "Kerfi",
"Grant access" : "Veita aðgengi",
@@ -16,8 +18,10 @@ OC.L10N.register(
"Error generating key pair" : "Villa við að útbúa nýtt lyklapar",
"All users. Type to select user or group." : "Allir notendur. Skrifaðu til að velja notanda eða hóp.",
"(group)" : "(hópur)",
+ "Compatibility with Mac NFD encoding (slow)" : "Samhæfni við Mac NFD kóðun (hægvirkt)",
"Admin defined" : "Skilgreindur kerfisstjóri",
"Saved" : "Vistað",
+ "Saving..." : "Er að vista ...",
"Save" : "Vista",
"Empty response from the server" : "Tómt svar frá þjóni móttekið",
"Couldn't access. Please logout and login to activate this mount point" : "Náði ekki aðgangi. Skráðu þig út og svo aftur inn til að virkja þennan tengipunkt",
@@ -61,8 +65,11 @@ OC.L10N.register(
"Identity endpoint URL" : "Endapunktur auðkennisslóðar (identity endpoint URL)",
"Rackspace" : "Rackspace",
"API key" : "API-lykill",
+ "Global Credentials" : "Víðvær innskráningarauðkenni",
+ "Log-in credentials, save in database" : "Innskráningarauðkenni, vista í gagnagrunni",
"Username and password" : "Notandanafn og lykilorð",
"Log-in credentials, save in session" : "Innskráningarauðkenni, vista í setu",
+ "User entered, store in database" : "Innskráður notandi, geyma í gagnagrunni",
"RSA public key" : "RSA-dreifilykill",
"Public key" : "Dreifilykill",
"Amazon S3" : "Amazon S3",
diff --git a/apps/files_external/l10n/is.json b/apps/files_external/l10n/is.json
index f5b3a1b1d33..5738ff738fb 100644
--- a/apps/files_external/l10n/is.json
+++ b/apps/files_external/l10n/is.json
@@ -5,6 +5,8 @@
"Step 1 failed. Exception: %s" : "Skref 1 mistókst. Undantekning: %s",
"Step 2 failed. Exception: %s" : "Skref 2 mistókst. Undantekning: %s",
"External storage" : "Ytri gagnageymsla",
+ "Dropbox App Configuration" : "Uppsetning Dropbox forrits",
+ "Google Drive App Configuration" : "Uppsetning Google Drive forrits",
"Personal" : "Einka",
"System" : "Kerfi",
"Grant access" : "Veita aðgengi",
@@ -14,8 +16,10 @@
"Error generating key pair" : "Villa við að útbúa nýtt lyklapar",
"All users. Type to select user or group." : "Allir notendur. Skrifaðu til að velja notanda eða hóp.",
"(group)" : "(hópur)",
+ "Compatibility with Mac NFD encoding (slow)" : "Samhæfni við Mac NFD kóðun (hægvirkt)",
"Admin defined" : "Skilgreindur kerfisstjóri",
"Saved" : "Vistað",
+ "Saving..." : "Er að vista ...",
"Save" : "Vista",
"Empty response from the server" : "Tómt svar frá þjóni móttekið",
"Couldn't access. Please logout and login to activate this mount point" : "Náði ekki aðgangi. Skráðu þig út og svo aftur inn til að virkja þennan tengipunkt",
@@ -59,8 +63,11 @@
"Identity endpoint URL" : "Endapunktur auðkennisslóðar (identity endpoint URL)",
"Rackspace" : "Rackspace",
"API key" : "API-lykill",
+ "Global Credentials" : "Víðvær innskráningarauðkenni",
+ "Log-in credentials, save in database" : "Innskráningarauðkenni, vista í gagnagrunni",
"Username and password" : "Notandanafn og lykilorð",
"Log-in credentials, save in session" : "Innskráningarauðkenni, vista í setu",
+ "User entered, store in database" : "Innskráður notandi, geyma í gagnagrunni",
"RSA public key" : "RSA-dreifilykill",
"Public key" : "Dreifilykill",
"Amazon S3" : "Amazon S3",
diff --git a/apps/files_external/l10n/pt_BR.js b/apps/files_external/l10n/pt_BR.js
index 39a6e766677..99aa844fb5b 100644
--- a/apps/files_external/l10n/pt_BR.js
+++ b/apps/files_external/l10n/pt_BR.js
@@ -31,7 +31,7 @@ OC.L10N.register(
"External mount error" : "Erro de montagem externa",
"external-storage" : "armazenamento-externo",
"Couldn't get the list of Windows network drive mount points: empty response from the server" : "Não foi possível obter a lista unidades de pontos de montagem da rede do Windows: resposta vazia a partir do servidor",
- "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor clique na linha vermelha(s) para mais informações",
+ "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Clique na(s) linha(s) vermelha(s) para mais informações",
"Please enter the credentials for the {mount} mount" : "Por favor, insira as credenciais para montar {mount}",
"Username" : "Nome de Usuário",
"Password" : "Senha",
diff --git a/apps/files_external/l10n/pt_BR.json b/apps/files_external/l10n/pt_BR.json
index 7d6a3b5b10d..aee79057b4d 100644
--- a/apps/files_external/l10n/pt_BR.json
+++ b/apps/files_external/l10n/pt_BR.json
@@ -29,7 +29,7 @@
"External mount error" : "Erro de montagem externa",
"external-storage" : "armazenamento-externo",
"Couldn't get the list of Windows network drive mount points: empty response from the server" : "Não foi possível obter a lista unidades de pontos de montagem da rede do Windows: resposta vazia a partir do servidor",
- "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Por favor clique na linha vermelha(s) para mais informações",
+ "Some of the configured external mount points are not connected. Please click on the red row(s) for more information" : "Alguns dos pontos de montagem externos configurados não estão conectados. Clique na(s) linha(s) vermelha(s) para mais informações",
"Please enter the credentials for the {mount} mount" : "Por favor, insira as credenciais para montar {mount}",
"Username" : "Nome de Usuário",
"Password" : "Senha",
diff --git a/apps/files_sharing/css/public.css b/apps/files_sharing/css/public.css
index c998501dad6..4c5f847f9ff 100644
--- a/apps/files_sharing/css/public.css
+++ b/apps/files_sharing/css/public.css
@@ -30,10 +30,15 @@
margin:0 auto;
}
+
#imgframe img,
#imgframe video {
- max-height:100%;
- max-width:100%;
+ max-height: 100% !important;
+ max-width: 100% !important;
+}
+#imgframe video {
+ width: 854px;
+ height: 480px;
}
#imgframe .text-preview {
diff --git a/apps/files_sharing/l10n/is.js b/apps/files_sharing/l10n/is.js
index c598282e23d..edd18ec47be 100644
--- a/apps/files_sharing/l10n/is.js
+++ b/apps/files_sharing/l10n/is.js
@@ -70,14 +70,20 @@ OC.L10N.register(
"No entries found in this folder" : "Engar skrár fundust í þessari möppu",
"Name" : "Nafn",
"Share time" : "Deilingartími",
+ "Expiration date" : "Gildir til",
"Sorry, this link doesn’t seem to work anymore." : "Því miður, þessi tengill virðist ekki virka lengur.",
"Reasons might be:" : "Mögulegar ástæður gætu verið:",
"the item was removed" : "atriðið var fjarlægt",
"the link expired" : "tengillinn er útrunninn",
"sharing is disabled" : "slökkt er á skráadeilingu",
"For more info, please ask the person who sent this link." : "Til að vita meira skaltu hafa samband við þann sem sendi þér þennan tengil.",
+ "Add to your Nextcloud" : "Bæta í þitt eigið Nextcloud",
"Download" : "Niðurhal",
"Download %s" : "Sækja %s",
- "Direct link" : "Beinn tengill"
+ "Direct link" : "Beinn tengill",
+ "Upload files to %s" : "Senda inn skrár á %s",
+ "Select or drop files" : "Veldu eða slepptu skrám",
+ "Uploading files…" : "Sendi inn skrár…",
+ "Uploaded files:" : "Innsendar skrár:"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/files_sharing/l10n/is.json b/apps/files_sharing/l10n/is.json
index 24b446ec9e8..6a64dd5f292 100644
--- a/apps/files_sharing/l10n/is.json
+++ b/apps/files_sharing/l10n/is.json
@@ -68,14 +68,20 @@
"No entries found in this folder" : "Engar skrár fundust í þessari möppu",
"Name" : "Nafn",
"Share time" : "Deilingartími",
+ "Expiration date" : "Gildir til",
"Sorry, this link doesn’t seem to work anymore." : "Því miður, þessi tengill virðist ekki virka lengur.",
"Reasons might be:" : "Mögulegar ástæður gætu verið:",
"the item was removed" : "atriðið var fjarlægt",
"the link expired" : "tengillinn er útrunninn",
"sharing is disabled" : "slökkt er á skráadeilingu",
"For more info, please ask the person who sent this link." : "Til að vita meira skaltu hafa samband við þann sem sendi þér þennan tengil.",
+ "Add to your Nextcloud" : "Bæta í þitt eigið Nextcloud",
"Download" : "Niðurhal",
"Download %s" : "Sækja %s",
- "Direct link" : "Beinn tengill"
+ "Direct link" : "Beinn tengill",
+ "Upload files to %s" : "Senda inn skrár á %s",
+ "Select or drop files" : "Veldu eða slepptu skrám",
+ "Uploading files…" : "Sendi inn skrár…",
+ "Uploaded files:" : "Innsendar skrár:"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/apps/systemtags/admin.php b/apps/systemtags/admin.php
new file mode 100644
index 00000000000..45ea577e8ab
--- /dev/null
+++ b/apps/systemtags/admin.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @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/>.
+ *
+ */
+
+$template = new \OCP\Template('systemtags', 'admin');
+return $template->fetchPage();
diff --git a/apps/systemtags/appinfo/app.php b/apps/systemtags/appinfo/app.php
index af91e5fdbcd..5a365c4ef15 100644
--- a/apps/systemtags/appinfo/app.php
+++ b/apps/systemtags/appinfo/app.php
@@ -78,6 +78,9 @@ $mapperListener = function(MapperEvent $event) use ($activityManager) {
$eventDispatcher->addListener(MapperEvent::EVENT_ASSIGN, $mapperListener);
$eventDispatcher->addListener(MapperEvent::EVENT_UNASSIGN, $mapperListener);
+$app = new \OCA\SystemTags\AppInfo\Application();
+$app->registerAdminPage();
+
$l = \OC::$server->getL10N('systemtags');
\OCA\Files\App::getNavigationManager()->add(
diff --git a/apps/systemtags/appinfo/info.xml b/apps/systemtags/appinfo/info.xml
index 1d75610f545..3521658ac20 100644
--- a/apps/systemtags/appinfo/info.xml
+++ b/apps/systemtags/appinfo/info.xml
@@ -5,7 +5,7 @@
<description>Collaborative tagging functionality which shares tags among users. Great for teams.
(If you are a provider with a multi-tenancy installation, it is advised to deactivate this app as tags are shared.)</description>
<licence>AGPL</licence>
- <author>Vincent Petry</author>
+ <author>Vincent Petry, Joas Schilling</author>
<default_enable/>
<version>1.0.0</version>
<dependencies>
diff --git a/apps/systemtags/js/admin.js b/apps/systemtags/js/admin.js
new file mode 100644
index 00000000000..ed21f82f3ba
--- /dev/null
+++ b/apps/systemtags/js/admin.js
@@ -0,0 +1,164 @@
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @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/>.
+ *
+ */
+
+(function() {
+ if (!OCA.SystemTags) {
+ /**
+ * @namespace
+ */
+ OCA.SystemTags = {};
+ }
+
+ OCA.SystemTags.Admin = {
+
+ collection: null,
+
+ init: function() {
+ var self = this;
+
+ this.collection = OC.SystemTags.collection;
+ this.collection.fetch({
+ success: function() {
+ $('#systemtag').select2(_.extend(self.select2));
+ }
+ });
+
+ $('#systemtag_submit').on('click', _.bind(this._onClickSubmit, this));
+ $('#systemtag_delete').on('click', _.bind(this._onClickDelete, this));
+ $('#systemtag_reset').on('click', _.bind(this._onClickReset, this));
+ },
+
+ /**
+ * Selecting a systemtag in select2
+ *
+ * @param {OC.SystemTags.SystemTagModel} tag
+ */
+ onSelectTag: function (tag) {
+ var level = 0;
+ if (tag.get('userVisible')) {
+ level += 2;
+ if (tag.get('userAssignable')) {
+ level += 1;
+ }
+ }
+
+ $('#systemtag_name').val(tag.get('name'));
+ $('#systemtag_level').val(level);
+
+ this._prepareForm(tag.get('id'));
+ },
+
+ /**
+ * Clicking the "Create"/"Update" button
+ */
+ _onClickSubmit: function () {
+ var level = parseInt($('#systemtag_level').val(), 10),
+ tagId = $('#systemtags').attr('data-systemtag-id');
+ var data = {
+ name: $('#systemtag_name').val(),
+ userVisible: level === 2 || level === 3,
+ userAssignable: level === 3
+ };
+
+ if (tagId) {
+ var model = this.collection.get(tagId);
+ model.save(data);
+ } else {
+ this.collection.create(data);
+ }
+
+ this._onClickReset();
+ },
+
+ /**
+ * Clicking the "Delete" button
+ */
+ _onClickDelete: function () {
+ var tagId = $('#systemtags').attr('data-systemtag-id');
+ var model = this.collection.get(tagId);
+ model.destroy();
+
+ this._onClickReset();
+ },
+
+ /**
+ * Clicking the "Reset" button
+ */
+ _onClickReset: function () {
+ $('#systemtag_name').val('');
+ $('#systemtag_level').val(3);
+ this._prepareForm(0);
+ },
+
+ /**
+ * Prepare the form for create/update
+ *
+ * @param {int} tagId
+ */
+ _prepareForm: function (tagId) {
+ if (tagId > 0) {
+ $('#systemtags').attr('data-systemtag-id', tagId);
+ $('#systemtag_delete').removeClass('hidden');
+ $('#systemtag_submit').val(t('systemtags_manager', 'Update'));
+ } else {
+ $('#systemtag').select2('val', '');
+ $('#systemtags').attr('data-systemtag-id', '');
+ $('#systemtag_delete').addClass('hidden');
+ $('#systemtag_submit').val(t('systemtags_manager', 'Create'));
+ }
+ },
+
+ /**
+ * Select2 options for the SystemTag dropdown
+ */
+ select2: {
+ allowClear: false,
+ multiple: false,
+ placeholder: t('systemtags_manager', 'Select tag…'),
+ query: _.debounce(function(query) {
+ query.callback({
+ results: OCA.SystemTags.Admin.collection.filterByName(query.term)
+ });
+ }, 100, true),
+ id: function(element) {
+ return element;
+ },
+ initSelection: function(element, callback) {
+ var selection = ($(element).val() || []).split('|').sort();
+ callback(selection);
+ },
+ formatResult: function (tag) {
+ return OC.SystemTags.getDescriptiveTag(tag);
+ },
+ formatSelection: function (tag) {
+ OCA.SystemTags.Admin.onSelectTag(tag);
+ return OC.SystemTags.getDescriptiveTag(tag);
+ },
+ escapeMarkup: function(m) {
+ return m;
+ }
+ }
+ };
+})();
+
+$(document).ready(function() {
+ OCA.SystemTags.Admin.init();
+});
+
diff --git a/apps/systemtags/l10n/ca.js b/apps/systemtags/l10n/ca.js
index 46d9d409662..3506940d2ee 100644
--- a/apps/systemtags/l10n/ca.js
+++ b/apps/systemtags/l10n/ca.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s ha des-assignat les marques de sistema de la %3$s a la %2$s",
"%s (restricted)" : "%s (restringit)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Nom",
"No files in here" : "No hi ha arxius",
"No entries found in this folder" : "No hi ha entrades en aquesta carpeta",
- "Name" : "Nom",
"Size" : "Mida",
"Modified" : "Modificat"
},
diff --git a/apps/systemtags/l10n/ca.json b/apps/systemtags/l10n/ca.json
index 9bb1d6fba83..46bdaabfacc 100644
--- a/apps/systemtags/l10n/ca.json
+++ b/apps/systemtags/l10n/ca.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s ha des-assignat les marques de sistema de la %3$s a la %2$s",
"%s (restricted)" : "%s (restringit)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Nom",
"No files in here" : "No hi ha arxius",
"No entries found in this folder" : "No hi ha entrades en aquesta carpeta",
- "Name" : "Nom",
"Size" : "Mida",
"Modified" : "Modificat"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/cs_CZ.js b/apps/systemtags/l10n/cs_CZ.js
index 2af8db9f183..d67754eb67e 100644
--- a/apps/systemtags/l10n/cs_CZ.js
+++ b/apps/systemtags/l10n/cs_CZ.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s odebral systémový tag %3$s ze %2$s",
"%s (restricted)" : "%s (omezeno)",
"%s (invisible)" : "%s (neviditelný)",
+ "Name" : "Název",
"No files in here" : "Žádné soubory",
"No entries found in this folder" : "V tomto adresáři nebylo nic nalezeno",
- "Name" : "Název",
"Size" : "Velikost",
"Modified" : "Upraveno"
},
diff --git a/apps/systemtags/l10n/cs_CZ.json b/apps/systemtags/l10n/cs_CZ.json
index c2c6536daa5..31e4b4bc1ed 100644
--- a/apps/systemtags/l10n/cs_CZ.json
+++ b/apps/systemtags/l10n/cs_CZ.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s odebral systémový tag %3$s ze %2$s",
"%s (restricted)" : "%s (omezeno)",
"%s (invisible)" : "%s (neviditelný)",
+ "Name" : "Název",
"No files in here" : "Žádné soubory",
"No entries found in this folder" : "V tomto adresáři nebylo nic nalezeno",
- "Name" : "Název",
"Size" : "Velikost",
"Modified" : "Upraveno"
},"pluralForm" :"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;"
diff --git a/apps/systemtags/l10n/de.js b/apps/systemtags/l10n/de.js
index 47b60136500..349d1562c77 100644
--- a/apps/systemtags/l10n/de.js
+++ b/apps/systemtags/l10n/de.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s hat den System-Tag %3$s von %2$s entfernt",
"%s (restricted)" : "%s (eingeschränkt)",
"%s (invisible)" : "%s (unsichtbar)",
+ "Name" : "Name",
"No files in here" : "Keine Dateien vorhanden",
"No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden",
- "Name" : "Name",
"Size" : "Größe",
"Modified" : "Geändert"
},
diff --git a/apps/systemtags/l10n/de.json b/apps/systemtags/l10n/de.json
index 100b3b32398..c74987a4722 100644
--- a/apps/systemtags/l10n/de.json
+++ b/apps/systemtags/l10n/de.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s hat den System-Tag %3$s von %2$s entfernt",
"%s (restricted)" : "%s (eingeschränkt)",
"%s (invisible)" : "%s (unsichtbar)",
+ "Name" : "Name",
"No files in here" : "Keine Dateien vorhanden",
"No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden",
- "Name" : "Name",
"Size" : "Größe",
"Modified" : "Geändert"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/de_DE.js b/apps/systemtags/l10n/de_DE.js
index 9a5566f7572..769a31911c6 100644
--- a/apps/systemtags/l10n/de_DE.js
+++ b/apps/systemtags/l10n/de_DE.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s hat den System-Tag %3$s von %2$s entfernt",
"%s (restricted)" : "%s (eingeschränkt)",
"%s (invisible)" : "%s (unsichtbar)",
+ "Name" : "Name",
"No files in here" : "Keine Dateien vorhanden",
"No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden",
- "Name" : "Name",
"Size" : "Größe",
"Modified" : "Geändert"
},
diff --git a/apps/systemtags/l10n/de_DE.json b/apps/systemtags/l10n/de_DE.json
index 77a5bbf0354..9e97b6c2459 100644
--- a/apps/systemtags/l10n/de_DE.json
+++ b/apps/systemtags/l10n/de_DE.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s hat den System-Tag %3$s von %2$s entfernt",
"%s (restricted)" : "%s (eingeschränkt)",
"%s (invisible)" : "%s (unsichtbar)",
+ "Name" : "Name",
"No files in here" : "Keine Dateien vorhanden",
"No entries found in this folder" : "Keine Einträge in diesem Ordner gefunden",
- "Name" : "Name",
"Size" : "Größe",
"Modified" : "Geändert"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/en_GB.js b/apps/systemtags/l10n/en_GB.js
index 09487413b04..2e64bf6720f 100644
--- a/apps/systemtags/l10n/en_GB.js
+++ b/apps/systemtags/l10n/en_GB.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s unassigned system tag %3$s from %2$s",
"%s (restricted)" : "%s (restricted)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Name",
"No files in here" : "No files in here",
"No entries found in this folder" : "No entries found in this folder",
- "Name" : "Name",
"Size" : "Size",
"Modified" : "Modified"
},
diff --git a/apps/systemtags/l10n/en_GB.json b/apps/systemtags/l10n/en_GB.json
index a6b50bd65c2..865bd76d220 100644
--- a/apps/systemtags/l10n/en_GB.json
+++ b/apps/systemtags/l10n/en_GB.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s unassigned system tag %3$s from %2$s",
"%s (restricted)" : "%s (restricted)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Name",
"No files in here" : "No files in here",
"No entries found in this folder" : "No entries found in this folder",
- "Name" : "Name",
"Size" : "Size",
"Modified" : "Modified"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/es.js b/apps/systemtags/l10n/es.js
index d9701e07a42..a261ab3a162 100644
--- a/apps/systemtags/l10n/es.js
+++ b/apps/systemtags/l10n/es.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s eliminó la asignación de etiqueta de sistema %3$s de %2$s",
"%s (restricted)" : "%s (restringido)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Nombre",
"No files in here" : "Aquí no hay archivos",
"No entries found in this folder" : "No hay entradas en esta carpeta",
- "Name" : "Nombre",
"Size" : "Tamaño",
"Modified" : "Modificado"
},
diff --git a/apps/systemtags/l10n/es.json b/apps/systemtags/l10n/es.json
index c310a231202..6c0a32910ea 100644
--- a/apps/systemtags/l10n/es.json
+++ b/apps/systemtags/l10n/es.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s eliminó la asignación de etiqueta de sistema %3$s de %2$s",
"%s (restricted)" : "%s (restringido)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Nombre",
"No files in here" : "Aquí no hay archivos",
"No entries found in this folder" : "No hay entradas en esta carpeta",
- "Name" : "Nombre",
"Size" : "Tamaño",
"Modified" : "Modificado"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/fr.js b/apps/systemtags/l10n/fr.js
index 387bc45643c..d4b9fa83147 100644
--- a/apps/systemtags/l10n/fr.js
+++ b/apps/systemtags/l10n/fr.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s a retiré l'étiquette collaborative %3$s à %2$s",
"%s (restricted)" : "%s (restreint)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Nom",
"No files in here" : "Aucun fichier",
"No entries found in this folder" : "Aucune entrée trouvée dans ce dossier",
- "Name" : "Nom",
"Size" : "Taille",
"Modified" : "Modifié"
},
diff --git a/apps/systemtags/l10n/fr.json b/apps/systemtags/l10n/fr.json
index 66b4d246dac..564cac7dd08 100644
--- a/apps/systemtags/l10n/fr.json
+++ b/apps/systemtags/l10n/fr.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s a retiré l'étiquette collaborative %3$s à %2$s",
"%s (restricted)" : "%s (restreint)",
"%s (invisible)" : "%s (invisible)",
+ "Name" : "Nom",
"No files in here" : "Aucun fichier",
"No entries found in this folder" : "Aucune entrée trouvée dans ce dossier",
- "Name" : "Nom",
"Size" : "Taille",
"Modified" : "Modifié"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
diff --git a/apps/systemtags/l10n/he.js b/apps/systemtags/l10n/he.js
index 9077fb2dcde..6a7d32cde10 100644
--- a/apps/systemtags/l10n/he.js
+++ b/apps/systemtags/l10n/he.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s הסיר/ה שיוך תגית מערכת %3$s מ- %2$s",
"%s (restricted)" : "%s (מוגבל)",
"%s (invisible)" : "%s (נסתר)",
+ "Name" : "שם",
"No files in here" : "אין כאן קבצים",
"No entries found in this folder" : "לא נמצאו כניסות לתיקייה זו",
- "Name" : "שם",
"Size" : "גודל",
"Modified" : "זמן שינוי"
},
diff --git a/apps/systemtags/l10n/he.json b/apps/systemtags/l10n/he.json
index b67b25afbd9..0d05d252f7e 100644
--- a/apps/systemtags/l10n/he.json
+++ b/apps/systemtags/l10n/he.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s הסיר/ה שיוך תגית מערכת %3$s מ- %2$s",
"%s (restricted)" : "%s (מוגבל)",
"%s (invisible)" : "%s (נסתר)",
+ "Name" : "שם",
"No files in here" : "אין כאן קבצים",
"No entries found in this folder" : "לא נמצאו כניסות לתיקייה זו",
- "Name" : "שם",
"Size" : "גודל",
"Modified" : "זמן שינוי"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/hu_HU.js b/apps/systemtags/l10n/hu_HU.js
index 783b90ece8a..109175f6447 100644
--- a/apps/systemtags/l10n/hu_HU.js
+++ b/apps/systemtags/l10n/hu_HU.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s elvette ezt a rendszer címkét %3$s tőle: %2$s",
"%s (restricted)" : "%s (korlátozott)",
"%s (invisible)" : "%s (láthatatlan)",
+ "Name" : "Név",
"No files in here" : "Itt nincsenek fájlok",
"No entries found in this folder" : "Nincsenek bejegyzések ebben a könyvtárban",
- "Name" : "Név",
"Size" : "Méret",
"Modified" : "Módosítva"
},
diff --git a/apps/systemtags/l10n/hu_HU.json b/apps/systemtags/l10n/hu_HU.json
index f89da5d3dfd..681f4d14ef5 100644
--- a/apps/systemtags/l10n/hu_HU.json
+++ b/apps/systemtags/l10n/hu_HU.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s elvette ezt a rendszer címkét %3$s tőle: %2$s",
"%s (restricted)" : "%s (korlátozott)",
"%s (invisible)" : "%s (láthatatlan)",
+ "Name" : "Név",
"No files in here" : "Itt nincsenek fájlok",
"No entries found in this folder" : "Nincsenek bejegyzések ebben a könyvtárban",
- "Name" : "Név",
"Size" : "Méret",
"Modified" : "Módosítva"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/is.js b/apps/systemtags/l10n/is.js
index 079fb251f82..efdeb28fc86 100644
--- a/apps/systemtags/l10n/is.js
+++ b/apps/systemtags/l10n/is.js
@@ -7,17 +7,25 @@ OC.L10N.register(
"Please select tags to filter by" : "Veldu merki til að sía eftir",
"No files found for the selected tags" : "Engar skrár fundust með völdum merkjum",
"<strong>System tags</strong> for a file have been modified" : "<strong>Kerfismerkjum</strong> á skrá hefur verið breytt",
+ "You assigned system tag %3$s" : "Þú úthlutaðir kerfismerkinu %3$s",
"%1$s assigned system tag %3$s" : "%1$s úthlutaði kerfismerki %3$s",
+ "You unassigned system tag %3$s" : "Þú tókst af úthlutun kerfismerkisins %3$s",
"%1$s unassigned system tag %3$s" : "%1$s tók af úthlutun kerfismerkis %3$s",
+ "You created system tag %2$s" : "Þú bjóst til kerfismerkið %2$s",
"%1$s created system tag %2$s" : "%1$s bjó til kerfismerki %2$s",
+ "You deleted system tag %2$s" : "Þú eyddir kerfismerkinu %2$s",
"%1$s deleted system tag %2$s" : "%1$s eyddi kerfismerki %2$s",
+ "You updated system tag %3$s to %2$s" : "Þú uppfærðir kerfismerki %3$s í %2$s",
"%1$s updated system tag %3$s to %2$s" : "%1$s uppfærði kerfismerki %3$s í %2$s",
+ "You assigned system tag %3$s to %2$s" : "Þú úthlutaðir kerfismerki %3$s á %2$s",
"%1$s assigned system tag %3$s to %2$s" : "%1$s úthlutaði kerfismerki %3$s á %2$s",
+ "You unassigned system tag %3$s from %2$s" : "Þú tókst kerfismerkið %3$s af %2$s",
"%1$s unassigned system tag %3$s from %2$s" : "%1$s tók kerfismerki %3$s af %2$s",
+ "%s (restricted)" : "%s (takmarkaður aðgangur)",
"%s (invisible)" : "%s (ósýnilegt)",
+ "Name" : "Heiti",
"No files in here" : "Engar skrár hér",
"No entries found in this folder" : "Engar skrár fundust í þessari möppu",
- "Name" : "Heiti",
"Size" : "Stærð",
"Modified" : "Breytt"
},
diff --git a/apps/systemtags/l10n/is.json b/apps/systemtags/l10n/is.json
index c51cc851932..d47891dabd1 100644
--- a/apps/systemtags/l10n/is.json
+++ b/apps/systemtags/l10n/is.json
@@ -5,17 +5,25 @@
"Please select tags to filter by" : "Veldu merki til að sía eftir",
"No files found for the selected tags" : "Engar skrár fundust með völdum merkjum",
"<strong>System tags</strong> for a file have been modified" : "<strong>Kerfismerkjum</strong> á skrá hefur verið breytt",
+ "You assigned system tag %3$s" : "Þú úthlutaðir kerfismerkinu %3$s",
"%1$s assigned system tag %3$s" : "%1$s úthlutaði kerfismerki %3$s",
+ "You unassigned system tag %3$s" : "Þú tókst af úthlutun kerfismerkisins %3$s",
"%1$s unassigned system tag %3$s" : "%1$s tók af úthlutun kerfismerkis %3$s",
+ "You created system tag %2$s" : "Þú bjóst til kerfismerkið %2$s",
"%1$s created system tag %2$s" : "%1$s bjó til kerfismerki %2$s",
+ "You deleted system tag %2$s" : "Þú eyddir kerfismerkinu %2$s",
"%1$s deleted system tag %2$s" : "%1$s eyddi kerfismerki %2$s",
+ "You updated system tag %3$s to %2$s" : "Þú uppfærðir kerfismerki %3$s í %2$s",
"%1$s updated system tag %3$s to %2$s" : "%1$s uppfærði kerfismerki %3$s í %2$s",
+ "You assigned system tag %3$s to %2$s" : "Þú úthlutaðir kerfismerki %3$s á %2$s",
"%1$s assigned system tag %3$s to %2$s" : "%1$s úthlutaði kerfismerki %3$s á %2$s",
+ "You unassigned system tag %3$s from %2$s" : "Þú tókst kerfismerkið %3$s af %2$s",
"%1$s unassigned system tag %3$s from %2$s" : "%1$s tók kerfismerki %3$s af %2$s",
+ "%s (restricted)" : "%s (takmarkaður aðgangur)",
"%s (invisible)" : "%s (ósýnilegt)",
+ "Name" : "Heiti",
"No files in here" : "Engar skrár hér",
"No entries found in this folder" : "Engar skrár fundust í þessari möppu",
- "Name" : "Heiti",
"Size" : "Stærð",
"Modified" : "Breytt"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
diff --git a/apps/systemtags/l10n/it.js b/apps/systemtags/l10n/it.js
index 4d6ae6b8a72..05901799052 100644
--- a/apps/systemtags/l10n/it.js
+++ b/apps/systemtags/l10n/it.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s ha rimosso l'etichetta di sistema %3$s da %2$s",
"%s (restricted)" : "%s (limitato)",
"%s (invisible)" : "%s (invisibile)",
+ "Name" : "Nome",
"No files in here" : "Qui non c'è alcun file",
"No entries found in this folder" : "Nessuna voce trovata in questa cartella",
- "Name" : "Nome",
"Size" : "Dimensione",
"Modified" : "Modificato"
},
diff --git a/apps/systemtags/l10n/it.json b/apps/systemtags/l10n/it.json
index fc7204f35a8..98c94b1d39a 100644
--- a/apps/systemtags/l10n/it.json
+++ b/apps/systemtags/l10n/it.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s ha rimosso l'etichetta di sistema %3$s da %2$s",
"%s (restricted)" : "%s (limitato)",
"%s (invisible)" : "%s (invisibile)",
+ "Name" : "Nome",
"No files in here" : "Qui non c'è alcun file",
"No entries found in this folder" : "Nessuna voce trovata in questa cartella",
- "Name" : "Nome",
"Size" : "Dimensione",
"Modified" : "Modificato"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/ja.js b/apps/systemtags/l10n/ja.js
index a5d2d2d0b38..e9b8d5aab4f 100644
--- a/apps/systemtags/l10n/ja.js
+++ b/apps/systemtags/l10n/ja.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s は%2$s から タグ %3$s を解除",
"%s (restricted)" : "%s (制限)",
"%s (invisible)" : "%s (不可視)",
+ "Name" : "名前",
"No files in here" : "ファイルがありません",
"No entries found in this folder" : "このフォルダーにはエントリーがありません",
- "Name" : "名前",
"Size" : "サイズ",
"Modified" : "更新日時"
},
diff --git a/apps/systemtags/l10n/ja.json b/apps/systemtags/l10n/ja.json
index b0d947b981f..874969fdd00 100644
--- a/apps/systemtags/l10n/ja.json
+++ b/apps/systemtags/l10n/ja.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s は%2$s から タグ %3$s を解除",
"%s (restricted)" : "%s (制限)",
"%s (invisible)" : "%s (不可視)",
+ "Name" : "名前",
"No files in here" : "ファイルがありません",
"No entries found in this folder" : "このフォルダーにはエントリーがありません",
- "Name" : "名前",
"Size" : "サイズ",
"Modified" : "更新日時"
},"pluralForm" :"nplurals=1; plural=0;"
diff --git a/apps/systemtags/l10n/nl.js b/apps/systemtags/l10n/nl.js
index 5d9b6ee97c2..765ec8679e2 100644
--- a/apps/systemtags/l10n/nl.js
+++ b/apps/systemtags/l10n/nl.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s verwijderde systeemtag %3$s van %2$s",
"%s (restricted)" : "%s (beperkt)",
"%s (invisible)" : "%s (onzichtbaar)",
+ "Name" : "Naam",
"No files in here" : "Hier geen bestanden",
"No entries found in this folder" : "Niets gevonden in deze map",
- "Name" : "Naam",
"Size" : "Grootte",
"Modified" : "Aangepast"
},
diff --git a/apps/systemtags/l10n/nl.json b/apps/systemtags/l10n/nl.json
index 14a8bfacf8a..1b5fcb1cdf4 100644
--- a/apps/systemtags/l10n/nl.json
+++ b/apps/systemtags/l10n/nl.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s verwijderde systeemtag %3$s van %2$s",
"%s (restricted)" : "%s (beperkt)",
"%s (invisible)" : "%s (onzichtbaar)",
+ "Name" : "Naam",
"No files in here" : "Hier geen bestanden",
"No entries found in this folder" : "Niets gevonden in deze map",
- "Name" : "Naam",
"Size" : "Grootte",
"Modified" : "Aangepast"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/pt_BR.js b/apps/systemtags/l10n/pt_BR.js
index 0b7bafaab49..cae092c39e1 100644
--- a/apps/systemtags/l10n/pt_BR.js
+++ b/apps/systemtags/l10n/pt_BR.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s etiqueta de sistema não atribuída %3$s de %2$s",
"%s (restricted)" : "%s (restrito)",
"%s (invisible)" : "%s (invisivel)",
+ "Name" : "Nome",
"No files in here" : "Nenhum arquivo aqui",
"No entries found in this folder" : "Nenhuma entrada foi encontrada nesta pasta",
- "Name" : "Nome",
"Size" : "Tamanho",
"Modified" : "Modificado"
},
diff --git a/apps/systemtags/l10n/pt_BR.json b/apps/systemtags/l10n/pt_BR.json
index cb38dfd1de3..27ee74fd8a2 100644
--- a/apps/systemtags/l10n/pt_BR.json
+++ b/apps/systemtags/l10n/pt_BR.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s etiqueta de sistema não atribuída %3$s de %2$s",
"%s (restricted)" : "%s (restrito)",
"%s (invisible)" : "%s (invisivel)",
+ "Name" : "Nome",
"No files in here" : "Nenhum arquivo aqui",
"No entries found in this folder" : "Nenhuma entrada foi encontrada nesta pasta",
- "Name" : "Nome",
"Size" : "Tamanho",
"Modified" : "Modificado"
},"pluralForm" :"nplurals=2; plural=(n > 1);"
diff --git a/apps/systemtags/l10n/pt_PT.js b/apps/systemtags/l10n/pt_PT.js
index bf33c8e9af9..d5844a64985 100644
--- a/apps/systemtags/l10n/pt_PT.js
+++ b/apps/systemtags/l10n/pt_PT.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s removeu a etiqueta do sistema %3$s de %2$s",
"%s (restricted)" : "%s (limitado)",
"%s (invisible)" : "%s (invisível)",
+ "Name" : "Nome",
"No files in here" : "Nenhuns ficheiros aqui",
"No entries found in this folder" : "Não foram encontradas entradas nesta pasta",
- "Name" : "Nome",
"Size" : "Tamanho",
"Modified" : "Modificado"
},
diff --git a/apps/systemtags/l10n/pt_PT.json b/apps/systemtags/l10n/pt_PT.json
index 1d6f99bfceb..59565b8053e 100644
--- a/apps/systemtags/l10n/pt_PT.json
+++ b/apps/systemtags/l10n/pt_PT.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s removeu a etiqueta do sistema %3$s de %2$s",
"%s (restricted)" : "%s (limitado)",
"%s (invisible)" : "%s (invisível)",
+ "Name" : "Nome",
"No files in here" : "Nenhuns ficheiros aqui",
"No entries found in this folder" : "Não foram encontradas entradas nesta pasta",
- "Name" : "Nome",
"Size" : "Tamanho",
"Modified" : "Modificado"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/ro.js b/apps/systemtags/l10n/ro.js
index 762e9406d89..4a2ee02f325 100644
--- a/apps/systemtags/l10n/ro.js
+++ b/apps/systemtags/l10n/ro.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s a înlăturat eticheta de sistem %3$s de la %2$s",
"%s (restricted)" : "%s (restricționat)",
"%s (invisible)" : "%s (invizibil)",
+ "Name" : "Nume",
"No files in here" : "Niciun fișier aici",
"No entries found in this folder" : "Niciun element găsit în acest director",
- "Name" : "Nume",
"Size" : "Mărime",
"Modified" : "Modificat"
},
diff --git a/apps/systemtags/l10n/ro.json b/apps/systemtags/l10n/ro.json
index ef1c127d145..20517cf41a2 100644
--- a/apps/systemtags/l10n/ro.json
+++ b/apps/systemtags/l10n/ro.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s a înlăturat eticheta de sistem %3$s de la %2$s",
"%s (restricted)" : "%s (restricționat)",
"%s (invisible)" : "%s (invizibil)",
+ "Name" : "Nume",
"No files in here" : "Niciun fișier aici",
"No entries found in this folder" : "Niciun element găsit în acest director",
- "Name" : "Nume",
"Size" : "Mărime",
"Modified" : "Modificat"
},"pluralForm" :"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
diff --git a/apps/systemtags/l10n/ru.js b/apps/systemtags/l10n/ru.js
index 97e27549a01..6f148ee51c7 100644
--- a/apps/systemtags/l10n/ru.js
+++ b/apps/systemtags/l10n/ru.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s убрал системную метку %3$s с %2$s",
"%s (restricted)" : "%s (ограничено)",
"%s (invisible)" : "%s (невидимые)",
+ "Name" : "Имя",
"No files in here" : "Здесь нет файлов",
"No entries found in this folder" : "Нет элементов в этом каталоге",
- "Name" : "Имя",
"Size" : "Размер",
"Modified" : "Изменён"
},
diff --git a/apps/systemtags/l10n/ru.json b/apps/systemtags/l10n/ru.json
index 39a27781fcf..718390ce639 100644
--- a/apps/systemtags/l10n/ru.json
+++ b/apps/systemtags/l10n/ru.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s убрал системную метку %3$s с %2$s",
"%s (restricted)" : "%s (ограничено)",
"%s (invisible)" : "%s (невидимые)",
+ "Name" : "Имя",
"No files in here" : "Здесь нет файлов",
"No entries found in this folder" : "Нет элементов в этом каталоге",
- "Name" : "Имя",
"Size" : "Размер",
"Modified" : "Изменён"
},"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
diff --git a/apps/systemtags/l10n/sl.js b/apps/systemtags/l10n/sl.js
index 727f03b8eb0..eda8054c9bf 100644
--- a/apps/systemtags/l10n/sl.js
+++ b/apps/systemtags/l10n/sl.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "Uporabnik %1$s je prevzel sistemsko oznako %3$s od %2$s",
"%s (restricted)" : "%s (omejeno)",
"%s (invisible)" : "%s (nevidno)",
+ "Name" : "Ime",
"No files in here" : "V mapi ni datotek",
"No entries found in this folder" : "V tej mapi ni najdenih predmetov.",
- "Name" : "Ime",
"Size" : "Velikost",
"Modified" : "Spremenjeno"
},
diff --git a/apps/systemtags/l10n/sl.json b/apps/systemtags/l10n/sl.json
index 6ec3bf25957..9231aeabf9c 100644
--- a/apps/systemtags/l10n/sl.json
+++ b/apps/systemtags/l10n/sl.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "Uporabnik %1$s je prevzel sistemsko oznako %3$s od %2$s",
"%s (restricted)" : "%s (omejeno)",
"%s (invisible)" : "%s (nevidno)",
+ "Name" : "Ime",
"No files in here" : "V mapi ni datotek",
"No entries found in this folder" : "V tej mapi ni najdenih predmetov.",
- "Name" : "Ime",
"Size" : "Velikost",
"Modified" : "Spremenjeno"
},"pluralForm" :"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
diff --git a/apps/systemtags/l10n/sq.js b/apps/systemtags/l10n/sq.js
index 284bb09fb6e..9312d671bd1 100644
--- a/apps/systemtags/l10n/sq.js
+++ b/apps/systemtags/l10n/sq.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s hoqi prej %2$s etiketën e sistemit %3$s",
"%s (restricted)" : "%s (e kufizuar)",
"%s (invisible)" : "%s (e padukshme)",
+ "Name" : "Emër",
"No files in here" : "S’ka kartela këtu",
"No entries found in this folder" : "S’u gjetën zëra në këtë dosje",
- "Name" : "Emër",
"Size" : "Madhësi",
"Modified" : "Ndryshuar më"
},
diff --git a/apps/systemtags/l10n/sq.json b/apps/systemtags/l10n/sq.json
index 8d2b6b6a33e..eed88992e5a 100644
--- a/apps/systemtags/l10n/sq.json
+++ b/apps/systemtags/l10n/sq.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s hoqi prej %2$s etiketën e sistemit %3$s",
"%s (restricted)" : "%s (e kufizuar)",
"%s (invisible)" : "%s (e padukshme)",
+ "Name" : "Emër",
"No files in here" : "S’ka kartela këtu",
"No entries found in this folder" : "S’u gjetën zëra në këtë dosje",
- "Name" : "Emër",
"Size" : "Madhësi",
"Modified" : "Ndryshuar më"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/l10n/sv.js b/apps/systemtags/l10n/sv.js
index 0a2be892f0b..be11b9f9ad3 100644
--- a/apps/systemtags/l10n/sv.js
+++ b/apps/systemtags/l10n/sv.js
@@ -23,9 +23,9 @@ OC.L10N.register(
"%1$s unassigned system tag %3$s from %2$s" : "%1$s tog bort tilldelad systemtagg %3$s från %2$s",
"%s (restricted)" : "%s (begränsad)",
"%s (invisible)" : "%s (osynlig)",
+ "Name" : "Namn",
"No files in here" : "Inga filer kunde hittas",
"No entries found in this folder" : "nga Filer hittades i denna mapp",
- "Name" : "Namn",
"Size" : "Storlek",
"Modified" : "Ändrad"
},
diff --git a/apps/systemtags/l10n/sv.json b/apps/systemtags/l10n/sv.json
index ac18892d320..214bd3b100a 100644
--- a/apps/systemtags/l10n/sv.json
+++ b/apps/systemtags/l10n/sv.json
@@ -21,9 +21,9 @@
"%1$s unassigned system tag %3$s from %2$s" : "%1$s tog bort tilldelad systemtagg %3$s från %2$s",
"%s (restricted)" : "%s (begränsad)",
"%s (invisible)" : "%s (osynlig)",
+ "Name" : "Namn",
"No files in here" : "Inga filer kunde hittas",
"No entries found in this folder" : "nga Filer hittades i denna mapp",
- "Name" : "Namn",
"Size" : "Storlek",
"Modified" : "Ändrad"
},"pluralForm" :"nplurals=2; plural=(n != 1);"
diff --git a/apps/systemtags/lib/AppInfo/Application.php b/apps/systemtags/lib/AppInfo/Application.php
new file mode 100644
index 00000000000..7cd49d6424b
--- /dev/null
+++ b/apps/systemtags/lib/AppInfo/Application.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @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\SystemTags\AppInfo;
+
+use OCP\AppFramework\App;
+
+class Application extends App {
+ public function __construct() {
+ parent::__construct('systemtags');
+ }
+
+ /**
+ * Register admin settings
+ */
+ public function registerAdminPage() {
+ \OCP\App::registerAdmin($this->getContainer()->getAppName(), 'admin');
+ }
+}
diff --git a/apps/systemtags/templates/admin.php b/apps/systemtags/templates/admin.php
new file mode 100644
index 00000000000..883e998ed61
--- /dev/null
+++ b/apps/systemtags/templates/admin.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
+ *
+ * @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/>.
+ *
+ */
+
+vendor_script('core', 'select2/select2');
+vendor_style('core', 'select2/select2');
+script('core', [
+ 'oc-backbone-webdav',
+ 'systemtags/systemtags',
+ 'systemtags/systemtagmodel',
+ 'systemtags/systemtagscollection',
+]);
+
+script('systemtags', 'admin');
+
+/** @var \OCP\IL10N $l */
+?>
+
+<form id="systemtags" class="section" data-systemtag-id="">
+ <h2><?php p($l->t('Collaborative tags')); ?></h2>
+
+ <input type="hidden" name="systemtag" id="systemtag" placeholder="<?php p($l->t('Select tag…')); ?>" style="width: 400px;" />
+
+ <br><br>
+
+ <input type="text" id="systemtag_name" name="systemtag_name" placeholder="<?php p($l->t('Name')); ?>" style="width: 200px;">
+
+ <span id="systemtag_delete" class="hidden">
+ <img src="<?php p(\OCP\Template::image_path('core', 'actions/delete.svg')); ?>" alt="<?php p($l->t('Delete')); ?>">
+ </span>
+
+ <br>
+
+ <select id="systemtag_level">
+ <option value="3"><?php p($l->t('Public')); ?></option>
+ <option value="2"><?php p($l->t('Restricted')); ?></option>
+ <option value="0"><?php p($l->t('Invisible')); ?></option>
+ </select>
+
+ <input type="button" id="systemtag_submit" value="<?php p($l->t('Create')); ?>">
+ <input type="button" id="systemtag_reset" value="<?php p($l->t('Reset')); ?>">
+</form>
diff --git a/apps/theming/appinfo/app.php b/apps/theming/appinfo/app.php
index 76580879ca1..5ef506e5acd 100644
--- a/apps/theming/appinfo/app.php
+++ b/apps/theming/appinfo/app.php
@@ -31,7 +31,7 @@ $linkToCSS = \OC::$server->getURLGenerator()->linkToRoute(
'v' => \OC::$server->getConfig()->getAppValue('theming', 'cachebuster', '0'),
]
);
-\OC_Util::addHeader(
+\OCP\Util::addHeader(
'link',
[
'rel' => 'stylesheet',
diff --git a/apps/theming/appinfo/routes.php b/apps/theming/appinfo/routes.php
index 073dacb789c..e062a68d69d 100644
--- a/apps/theming/appinfo/routes.php
+++ b/apps/theming/appinfo/routes.php
@@ -24,9 +24,7 @@
*
*/
-namespace OCA\Theming\AppInfo;
-
-(new \OCP\AppFramework\App('theming'))->registerRoutes($this, array('routes' => array(
+return ['routes' => [
[
'name' => 'Theming#updateStylesheet',
'url' => '/ajax/updateStylesheet',
@@ -57,5 +55,5 @@ namespace OCA\Theming\AppInfo;
'url' => '/loginbackground',
'verb' => 'GET',
],
-)));
+]];
diff --git a/apps/theming/js/settings-admin.js b/apps/theming/js/settings-admin.js
index 941ec5c711b..01ff9123842 100644
--- a/apps/theming/js/settings-admin.js
+++ b/apps/theming/js/settings-admin.js
@@ -46,29 +46,46 @@ function calculateLuminance(rgb) {
return (0.299*r + 0.587*g + 0.114*b)/255;
}
+function generateRadioButton(color) {
+ var radioButton = '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">' +
+ '<path d="M8 1a7 7 0 0 0-7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0-7-7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6zm0 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z" fill="' + color + '"/></svg>';
+ return btoa(radioButton);
+}
+
function preview(setting, value) {
if (setting === 'color') {
var headerClass = document.getElementById('header');
var expandDisplayNameClass = document.getElementById('expandDisplayName');
var headerAppName = headerClass.getElementsByClassName('header-appname')[0];
var textColor, icon;
+ var luminance = calculateLuminance(value);
+ var elementColor = value;
- if (calculateLuminance(value) > 0.5) {
+ if (luminance > 0.5) {
textColor = "#000000";
icon = 'caret-dark';
} else {
textColor = "#ffffff";
icon = 'caret';
}
+ if (luminance>0.8) {
+ elementColor = '#555555';
+ }
headerClass.style.background = value;
headerClass.style.backgroundImage = '../img/logo-icon.svg';
expandDisplayNameClass.style.color = textColor;
headerAppName.style.color = textColor;
- $(headerClass).find('.icon-caret').each(function() {
- $(this).css('background-image', "url('" + OC.getRootPath() + '/core/img/actions/' + icon + ".svg')");
- });
+ $('#previewStyles').html(
+ '#header .icon-caret { background-image: url(\'' + OC.getRootPath() + '/core/img/actions/' + icon + '.svg\') }' +
+ 'input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' +
+ 'background-image:url(\'' + OC.getRootPath() + '/core/img/actions/checkmark-white.svg\');' +
+ 'background-color: ' + elementColor + '; background-position: center center; background-size:contain;' +
+ 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;}' +
+ 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' +
+ 'background-image: url(\'data:image/svg+xml;base64,' + generateRadioButton(elementColor) + '\'); }'
+ );
}
if (setting === 'logoMime') {
console.log(setting);
@@ -87,6 +104,8 @@ function preview(setting, value) {
$(document).ready(function () {
$('#theming [data-toggle="tooltip"]').tooltip();
+ $('html > head').append($('<style type="text/css" id="previewStyles"></style>'));
+
var uploadParamsLogo = {
pasteZone: null,
dropZone: null,
diff --git a/apps/theming/lib/controller/themingcontroller.php b/apps/theming/lib/Controller/ThemingController.php
index 3e5d6f3e0d1..55391619f3c 100644
--- a/apps/theming/lib/controller/themingcontroller.php
+++ b/apps/theming/lib/Controller/ThemingController.php
@@ -30,7 +30,10 @@ namespace OCA\Theming\Controller;
use OCA\Theming\Template;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\DataDownloadResponse;
use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\Http\StreamResponse;
+use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Files\IRootFolder;
use OCP\IConfig;
use OCP\IL10N;
@@ -47,6 +50,10 @@ use OCA\Theming\Util;
class ThemingController extends Controller {
/** @var Template */
private $template;
+ /** @var Util */
+ private $util;
+ /** @var ITimeFactory */
+ private $timeFactory;
/** @var IL10N */
private $l;
/** @var IConfig */
@@ -61,6 +68,8 @@ class ThemingController extends Controller {
* @param IRequest $request
* @param IConfig $config
* @param Template $template
+ * @param Util $util
+ * @param ITimeFactory $timeFactory
* @param IL10N $l
* @param IRootFolder $rootFolder
*/
@@ -69,12 +78,16 @@ class ThemingController extends Controller {
IRequest $request,
IConfig $config,
Template $template,
+ Util $util,
+ ITimeFactory $timeFactory,
IL10N $l,
IRootFolder $rootFolder
) {
parent::__construct($appName, $request);
$this->template = $template;
+ $this->util = $util;
+ $this->timeFactory = $timeFactory;
$this->l = $l;
$this->config = $config;
$this->rootFolder = $rootFolder;
@@ -166,7 +179,7 @@ class ThemingController extends Controller {
* @PublicPage
* @NoCSRFRequired
*
- * @return Http\StreamResponse
+ * @return StreamResponse|DataResponse
*/
public function getLogo() {
$pathToLogo = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/') . '/themedinstancelogo';
@@ -174,10 +187,9 @@ class ThemingController extends Controller {
return new DataResponse();
}
- \OC_Response::setExpiresHeader(gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
- \OC_Response::enableCaching();
$response = new Http\StreamResponse($pathToLogo);
$response->cacheFor(3600);
+ $response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime()));
$response->addHeader('Content-Disposition', 'attachment');
$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'logoMime', ''));
return $response;
@@ -187,7 +199,7 @@ class ThemingController extends Controller {
* @PublicPage
* @NoCSRFRequired
*
- * @return Http\StreamResponse
+ * @return StreamResponse|DataResponse
*/
public function getLoginBackground() {
$pathToLogo = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data/') . '/themedbackgroundlogo';
@@ -195,10 +207,9 @@ class ThemingController extends Controller {
return new DataResponse();
}
- \OC_Response::setExpiresHeader(gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
- \OC_Response::enableCaching();
- $response = new Http\StreamResponse($pathToLogo);
+ $response = new StreamResponse($pathToLogo);
$response->cacheFor(3600);
+ $response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime()));
$response->addHeader('Content-Disposition', 'attachment');
$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, 'backgroundMime', ''));
return $response;
@@ -208,46 +219,72 @@ class ThemingController extends Controller {
* @NoCSRFRequired
* @PublicPage
*
- * @return Http\DataDownloadResponse
+ * @return DataDownloadResponse
*/
public function getStylesheet() {
$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
$responseCss = '';
$color = $this->config->getAppValue($this->appName, 'color');
+ $elementColor = $this->util->elementColor($color);
if($color !== '') {
$responseCss .= sprintf(
- '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}',
+ '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
$color
);
+ $responseCss .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
+ 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
+ 'background-color: %s; background-position: center center; background-size:contain;' .
+ 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
+ "}\n",
+ \OC::$WEBROOT,
+ $elementColor
+ );
+ $responseCss .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
+ 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($elementColor).'\');' .
+ "}\n";
+ $responseCss .= '
+ #firstrunwizard .firstrunwizard-header {
+ background-color: ' . $color . ';
+ }
+ #firstrunwizard p a {
+ color: ' . $color . ';
+ }
+ ';
+
}
$logo = $this->config->getAppValue($this->appName, 'logoMime');
if($logo !== '') {
- $responseCss .= sprintf('#header .logo {
- background-image: url(\'./logo?v='.$cacheBusterValue.'\');
- background-size: contain;
- }
- #header .logo-icon {
- background-image: url(\'./logo?v='.$cacheBusterValue.'\');
- background-size: contain;
- }'
+ $responseCss .= sprintf(
+ '#header .logo {' .
+ 'background-image: url(\'./logo?v='.$cacheBusterValue.'\')' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#header .logo-icon {' .
+ 'background-image: url(\'./logo?v='.$cacheBusterValue.'\');' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#firstrunwizard .firstrunwizard-header .logo {' .
+ 'background-image: url(\'./logo?v='.$cacheBusterValue.'\');' .
+ 'background-size: contain;' .
+ '}' . "\n"
);
}
$backgroundLogo = $this->config->getAppValue($this->appName, 'backgroundMime');
if($backgroundLogo !== '') {
- $responseCss .= '#body-login {
- background-image: url(\'./loginbackground?v='.$cacheBusterValue.'\');
- }';
+ $responseCss .= '#body-login {background-image: url(\'./loginbackground?v='.$cacheBusterValue.'\');}' . "\n";
+ $responseCss .= '#firstrunwizard .firstrunwizard-header {' .
+ 'background-image: url(\'./loginbackground?v='.$cacheBusterValue.'\');' .
+ '}' . "\n";
}
- if(Util::invertTextColor($color)) {
- $responseCss .= '#header .header-appname, #expandDisplayName { color: #000000; } ';
- $responseCss .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); } ';
- $responseCss .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }';
- $responseCss .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }';
+ if($this->util->invertTextColor($color)) {
+ $responseCss .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n";
+ $responseCss .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n";
+ $responseCss .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n";
+ $responseCss .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n";
}
- \OC_Response::setExpiresHeader(gmdate('D, d M Y H:i:s', time() + (60*60*24*45)) . ' GMT');
- \OC_Response::enableCaching();
- $response = new Http\DataDownloadResponse($responseCss, 'style', 'text/css');
+ $response = new DataDownloadResponse($responseCss, 'style', 'text/css');
+ $response->addHeader('Expires', date(\DateTime::RFC2822, $this->timeFactory->getTime()));
$response->cacheFor(3600);
return $response;
}
diff --git a/apps/theming/lib/template.php b/apps/theming/lib/Template.php
index 8cd2befc1d1..25730aad95b 100644
--- a/apps/theming/lib/template.php
+++ b/apps/theming/lib/Template.php
@@ -40,7 +40,7 @@ use OCP\IURLGenerator;
class Template extends \OC_Defaults {
/** @var IConfig */
private $config;
- /** @var IL10N */
+ /** @var IL10N */
private $l;
/** @var IURLGenerator */
private $urlGenerator;
diff --git a/apps/theming/lib/util.php b/apps/theming/lib/Util.php
index 2088650b19d..71ed0958e42 100644
--- a/apps/theming/lib/util.php
+++ b/apps/theming/lib/Util.php
@@ -29,8 +29,8 @@ class Util {
* @param string $color rgb color value
* @return bool
*/
- public static function invertTextColor($color) {
- $l = self::calculateLuminance($color);
+ public function invertTextColor($color) {
+ $l = $this->calculateLuminance($color);
if($l>0.5) {
return true;
} else {
@@ -39,10 +39,25 @@ class Util {
}
/**
+ * get color for on-page elements:
+ * theme color by default, grey if theme color is to bright
+ * @param $color
+ * @return string
+ */
+ public function elementColor($color) {
+ $l = $this->calculateLuminance($color);
+ if($l>0.8) {
+ return '#555555';
+ } else {
+ return $color;
+ }
+ }
+
+ /**
* @param string $color rgb color value
* @return float
*/
- public static function calculateLuminance($color) {
+ public function calculateLuminance($color) {
$hex = preg_replace("/[^0-9A-Fa-f]/", '', $color);
if (strlen($hex) === 3) {
$hex = $hex{0} . $hex{0} . $hex{1} . $hex{1} . $hex{2} . $hex{2};
@@ -56,4 +71,14 @@ class Util {
return (0.299 * $r + 0.587 * $g + 0.114 * $b)/255;
}
+ /**
+ * @param $color
+ * @return string base64 encoded radio button svg
+ */
+ public function generateRadioButton($color) {
+ $radioButtonIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">' .
+ '<path d="M8 1a7 7 0 0 0-7 7 7 7 0 0 0 7 7 7 7 0 0 0 7-7 7 7 0 0 0-7-7zm0 1a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6 6 6 0 0 1 6-6zm0 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z" fill="'.$color.'"/></svg>';
+ return base64_encode($radioButtonIcon);
+ }
+
}
diff --git a/apps/theming/settings/settings-admin.php b/apps/theming/settings/settings-admin.php
index d9aa05cfca0..8ef499789e8 100644
--- a/apps/theming/settings/settings-admin.php
+++ b/apps/theming/settings/settings-admin.php
@@ -23,8 +23,6 @@
*
*/
-\OC_Util::checkAdminUser();
-
$config = \OC::$server->getConfig();
$l = \OC::$server->getL10N('theming');
$urlGenerator = \OC::$server->getURLGenerator();
@@ -40,7 +38,7 @@ if ($theme !== '') {
$errorMessage = $l->t('You already use a custom theme');
}
-$template = new OCP\Template('theming', 'settings-admin');
+$template = new \OCP\Template('theming', 'settings-admin');
$template->assign('themable', $themable);
$template->assign('errorMessage', $errorMessage);
diff --git a/apps/theming/tests/lib/controller/ThemingControllerTest.php b/apps/theming/tests/Controller/ThemingControllerTest.php
index 24eb0510f99..933faf8a0a1 100644
--- a/apps/theming/tests/lib/controller/ThemingControllerTest.php
+++ b/apps/theming/tests/Controller/ThemingControllerTest.php
@@ -26,6 +26,7 @@ namespace OCA\Theming\Tests\Controller;
use OCA\Theming\Controller\ThemingController;
use OCA\Theming\Template;
+use OCA\Theming\Util;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\Files\IRootFolder;
@@ -41,6 +42,10 @@ class ThemingControllerTest extends TestCase {
private $config;
/** @var Template */
private $template;
+ /** @var Util */
+ private $util;
+ /** @var \OCP\AppFramework\Utility\ITimeFactory */
+ private $timeFactory;
/** @var IL10N */
private $l10n;
/** @var ThemingController */
@@ -53,14 +58,24 @@ class ThemingControllerTest extends TestCase {
$this->config = $this->getMock('\\OCP\\IConfig');
$this->template = $this->getMockBuilder('\\OCA\\Theming\\Template')
->disableOriginalConstructor()->getMock();
+ $this->util = new Util();
+ $this->timeFactory = $this->getMockBuilder('OCP\AppFramework\Utility\ITimeFactory')
+ ->disableOriginalConstructor()
+ ->getMock();
$this->l10n = $this->getMock('\\OCP\\IL10N');
$this->rootFolder = $this->getMock('\\OCP\\Files\\IRootFolder');
+ $this->timeFactory->expects($this->any())
+ ->method('getTime')
+ ->willReturn(123);
+
$this->themingController = new ThemingController(
'theming',
$this->request,
$this->config,
$this->template,
+ $this->util,
+ $this->timeFactory,
$this->l10n,
$this->rootFolder
);
@@ -272,6 +287,7 @@ class ThemingControllerTest extends TestCase {
@$expected = new Http\StreamResponse($tmpLogo);
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
$expected->addHeader('Content-Disposition', 'attachment');
$expected->addHeader('Content-Type', 'text/svg');
@$this->assertEquals($expected, $this->themingController->getLogo());
@@ -300,12 +316,16 @@ class ThemingControllerTest extends TestCase {
@$expected = new Http\StreamResponse($tmpLogo);
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
$expected->addHeader('Content-Disposition', 'attachment');
$expected->addHeader('Content-Type', 'image/png');
@$this->assertEquals($expected, $this->themingController->getLoginBackground());
}
public function testGetStylesheetWithOnlyColor() {
+
+ $color = '#000';
+
$this->config
->expects($this->at(0))
->method('getAppValue')
@@ -315,7 +335,7 @@ class ThemingControllerTest extends TestCase {
->expects($this->at(1))
->method('getAppValue')
->with('theming', 'color', '')
- ->willReturn('#000');
+ ->willReturn($color);
$this->config
->expects($this->at(2))
->method('getAppValue')
@@ -327,12 +347,42 @@ class ThemingControllerTest extends TestCase {
->with('theming', 'backgroundMime', '')
->willReturn('');
- $expected = new Http\DataDownloadResponse('#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #000}', 'style', 'text/css');
+ $expectedData = sprintf(
+ '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
+ $color
+ );
+ $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
+ 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
+ 'background-color: %s; background-position: center center; background-size:contain;' .
+ 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
+ "}\n",
+ \OC::$WEBROOT,
+ $color
+ );
+ $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
+ 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($color).'\');' .
+ "}\n";
+
+ $expectedData .= '
+ #firstrunwizard .firstrunwizard-header {
+ background-color: ' . $color . ';
+ }
+ #firstrunwizard p a {
+ color: ' . $color . ';
+ }
+ ';
+
+ $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css');
+
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
@$this->assertEquals($expected, $this->themingController->getStylesheet());
}
public function testGetStylesheetWithOnlyColorInvert() {
+
+ $color = '#fff';
+
$this->config
->expects($this->at(0))
->method('getAppValue')
@@ -342,7 +392,7 @@ class ThemingControllerTest extends TestCase {
->expects($this->at(1))
->method('getAppValue')
->with('theming', 'color', '')
- ->willReturn('#fff');
+ ->willReturn($color);
$this->config
->expects($this->at(2))
->method('getAppValue')
@@ -354,8 +404,39 @@ class ThemingControllerTest extends TestCase {
->with('theming', 'backgroundMime', '')
->willReturn('');
- $expected = new Http\DataDownloadResponse('#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #fff}#header .header-appname, #expandDisplayName { color: #000000; } #header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); } .searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }', 'style', 'text/css');
+ $expectedData = sprintf(
+ '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
+ $color
+ );
+ $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
+ 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
+ 'background-color: #555555; background-position: center center; background-size:contain;' .
+ 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
+ "}\n",
+ \OC::$WEBROOT
+ );
+ $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
+ 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton('#555555').'\');' .
+ "}\n";
+
+ $expectedData .= '
+ #firstrunwizard .firstrunwizard-header {
+ background-color: ' . $color . ';
+ }
+ #firstrunwizard p a {
+ color: ' . $color . ';
+ }
+ ';
+ $expectedData .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n";
+ $expectedData .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n";
+ $expectedData .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n";
+ $expectedData .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n";
+
+
+ $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css');
+
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
@$this->assertEquals($expected, $this->themingController->getStylesheet());
}
@@ -381,15 +462,23 @@ class ThemingControllerTest extends TestCase {
->with('theming', 'backgroundMime', '')
->willReturn('');
- $expected = new Http\DataDownloadResponse('#header .logo {
- background-image: url(\'./logo?v=0\');
- background-size: contain;
- }
- #header .logo-icon {
- background-image: url(\'./logo?v=0\');
- background-size: contain;
- }', 'style', 'text/css');
+ $expectedData = '#header .logo {' .
+ 'background-image: url(\'./logo?v=0\')' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#header .logo-icon {' .
+ 'background-image: url(\'./logo?v=0\');' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#firstrunwizard .firstrunwizard-header .logo {' .
+ 'background-image: url(\'./logo?v=0\');' .
+ 'background-size: contain;' .
+ '}' . "\n";
+
+ $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css');
+
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
@$this->assertEquals($expected, $this->themingController->getStylesheet());
}
@@ -415,14 +504,22 @@ class ThemingControllerTest extends TestCase {
->with('theming', 'backgroundMime', '')
->willReturn('text/svg');
- $expected = new Http\DataDownloadResponse('#body-login {
- background-image: url(\'./loginbackground?v=0\');
- }', 'style', 'text/css');
+ $expectedData = '#body-login {background-image: url(\'./loginbackground?v=0\');}' . "\n";
+ $expectedData .= '#firstrunwizard .firstrunwizard-header {' .
+ 'background-image: url(\'./loginbackground?v=0\');' .
+ '}' . "\n";
+
+ $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css');
+
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
@$this->assertEquals($expected, $this->themingController->getStylesheet());
}
public function testGetStylesheetWithAllCombined() {
+
+ $color = '#000';
+
$this->config
->expects($this->at(0))
->method('getAppValue')
@@ -432,7 +529,7 @@ class ThemingControllerTest extends TestCase {
->expects($this->at(1))
->method('getAppValue')
->with('theming', 'color', '')
- ->willReturn('#000');
+ ->willReturn($color);
$this->config
->expects($this->at(2))
->method('getAppValue')
@@ -444,20 +541,58 @@ class ThemingControllerTest extends TestCase {
->with('theming', 'backgroundMime', '')
->willReturn('image/png');
- $expected = new Http\DataDownloadResponse('#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #000}#header .logo {
- background-image: url(\'./logo?v=0\');
- background-size: contain;
- }
- #header .logo-icon {
- background-image: url(\'./logo?v=0\');
- background-size: contain;
- }#body-login {
- background-image: url(\'./loginbackground?v=0\');
- }', 'style', 'text/css');
+ $expectedData = sprintf(
+ '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
+ $color);
+
+ $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
+ 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
+ 'background-color: %s; background-position: center center; background-size:contain;' .
+ 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
+ "}\n",
+ \OC::$WEBROOT,
+ $color
+ );
+ $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
+ 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton($color).'\');' .
+ "}\n";
+ $expectedData .= '
+ #firstrunwizard .firstrunwizard-header {
+ background-color: ' . $color . ';
+ }
+ #firstrunwizard p a {
+ color: ' . $color . ';
+ }
+ ';
+ $expectedData .= sprintf(
+ '#header .logo {' .
+ 'background-image: url(\'./logo?v=0\')' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#header .logo-icon {' .
+ 'background-image: url(\'./logo?v=0\');' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#firstrunwizard .firstrunwizard-header .logo {' .
+ 'background-image: url(\'./logo?v=0\');' .
+ 'background-size: contain;' .
+ '}' . "\n"
+ );
+ $expectedData .= '#body-login {background-image: url(\'./loginbackground?v=0\');}' . "\n";
+ $expectedData .= '#firstrunwizard .firstrunwizard-header {' .
+ 'background-image: url(\'./loginbackground?v=0\');' .
+ '}' . "\n";
+ $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css');
+
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
@$this->assertEquals($expected, $this->themingController->getStylesheet());
}
+
public function testGetStylesheetWithAllCombinedInverted() {
+
+ $color = '#fff';
+
$this->config
->expects($this->at(0))
->method('getAppValue')
@@ -479,17 +614,55 @@ class ThemingControllerTest extends TestCase {
->with('theming', 'backgroundMime', '')
->willReturn('image/png');
- $expected = new Http\DataDownloadResponse('#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: #fff}#header .logo {
- background-image: url(\'./logo?v=0\');
- background-size: contain;
- }
- #header .logo-icon {
- background-image: url(\'./logo?v=0\');
- background-size: contain;
- }#body-login {
- background-image: url(\'./loginbackground?v=0\');
- }#header .header-appname, #expandDisplayName { color: #000000; } #header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); } .searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }', 'style', 'text/css');
+
+ $expectedData = sprintf(
+ '#body-user #header,#body-settings #header,#body-public #header,#body-login,.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid {background-color: %s}' . "\n",
+ $color);
+
+ $expectedData .= sprintf('input[type="checkbox"].checkbox:checked:enabled:not(.checkbox--white) + label:before {' .
+ 'background-image:url(\'%s/core/img/actions/checkmark-white.svg\');' .
+ 'background-color: #555555; background-position: center center; background-size:contain;' .
+ 'width:12px; height:12px; padding:0; margin:2px 6px 6px 2px; border-radius:1px;' .
+ "}\n",
+ \OC::$WEBROOT
+ );
+ $expectedData .= 'input[type="radio"].radio:checked:not(.radio--white):not(:disabled) + label:before {' .
+ 'background-image: url(\'data:image/svg+xml;base64,'.$this->util->generateRadioButton('#555555').'\');' .
+ "}\n";
+ $expectedData .= '
+ #firstrunwizard .firstrunwizard-header {
+ background-color: ' . $color . ';
+ }
+ #firstrunwizard p a {
+ color: ' . $color . ';
+ }
+ ';
+ $expectedData .= sprintf(
+ '#header .logo {' .
+ 'background-image: url(\'./logo?v=0\')' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#header .logo-icon {' .
+ 'background-image: url(\'./logo?v=0\');' .
+ 'background-size: contain;' .
+ '}' . "\n" .
+ '#firstrunwizard .firstrunwizard-header .logo {' .
+ 'background-image: url(\'./logo?v=0\');' .
+ 'background-size: contain;' .
+ '}' . "\n"
+ );
+ $expectedData .= '#body-login {background-image: url(\'./loginbackground?v=0\');}' . "\n";
+ $expectedData .= '#firstrunwizard .firstrunwizard-header {' .
+ 'background-image: url(\'./loginbackground?v=0\');' .
+ '}' . "\n";
+ $expectedData .= '#header .header-appname, #expandDisplayName { color: #000000; }' . "\n";
+ $expectedData .= '#header .icon-caret { background-image: url(\'' . \OC::$WEBROOT . '/core/img/actions/caret-dark.svg\'); }' . "\n";
+ $expectedData .= '.searchbox input[type="search"] { background: transparent url(\'' . \OC::$WEBROOT . '/core/img/actions/search.svg\') no-repeat 6px center; color: #000; }' . "\n";
+ $expectedData .= '.searchbox input[type="search"]:focus,.searchbox input[type="search"]:active,.searchbox input[type="search"]:valid { color: #000; border: 1px solid rgba(0, 0, 0, .5); }' . "\n";
+ $expected = new Http\DataDownloadResponse($expectedData, 'style', 'text/css');
+
$expected->cacheFor(3600);
+ $expected->addHeader('Expires', date(\DateTime::RFC2822, 123));
@$this->assertEquals($expected, $this->themingController->getStylesheet());
}
diff --git a/apps/theming/tests/lib/TemplateTest.php b/apps/theming/tests/TemplateTest.php
index c3c792657ec..c3c792657ec 100644
--- a/apps/theming/tests/lib/TemplateTest.php
+++ b/apps/theming/tests/TemplateTest.php
diff --git a/apps/theming/tests/UtilTest.php b/apps/theming/tests/UtilTest.php
new file mode 100644
index 00000000000..c7fc385d25d
--- /dev/null
+++ b/apps/theming/tests/UtilTest.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
+ *
+ * @author Julius Haertl <jus@bitgrid.net>
+ *
+ * @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\Theming\Tests;
+
+use OCA\Theming\Util;
+use Test\TestCase;
+
+class UtilTest extends TestCase {
+
+ /** @var Util */
+ protected $util;
+
+ protected function setUp() {
+ parent::setUp();
+ $this->util = new Util();
+ }
+
+ public function testInvertTextColorLight() {
+ $invert = $this->util->invertTextColor('#ffffff');
+ $this->assertEquals(true, $invert);
+ }
+
+ public function testInvertTextColorDark() {
+ $invert = $this->util->invertTextColor('#000000');
+ $this->assertEquals(false, $invert);
+ }
+
+ public function testCalculateLuminanceLight() {
+ $luminance = $this->util->calculateLuminance('#ffffff');
+ $this->assertEquals(1, $luminance);
+ }
+
+ public function testCalculateLuminanceDark() {
+ $luminance = $this->util->calculateLuminance('#000000');
+ $this->assertEquals(0, $luminance);
+ }
+
+ public function testCalculateLuminanceLightShorthand() {
+ $luminance = $this->util->calculateLuminance('#fff');
+ $this->assertEquals(1, $luminance);
+ }
+
+ public function testCalculateLuminanceDarkShorthand() {
+ $luminance = $this->util->calculateLuminance('#000');
+ $this->assertEquals(0, $luminance);
+ }
+ public function testInvertTextColorInvalid() {
+ $invert = $this->util->invertTextColor('aaabbbcccddd123');
+ $this->assertEquals(false, $invert);
+ }
+
+ public function testInvertTextColorEmpty() {
+ $invert = $this->util->invertTextColor('');
+ $this->assertEquals(false, $invert);
+ }
+
+ public function testElementColorDefault() {
+ $elementColor = $this->util->elementColor("#000000");
+ $this->assertEquals('#000000', $elementColor);
+ }
+
+ public function testElementColorOnBrightBackground() {
+ $elementColor = $this->util->elementColor('#ffffff');
+ $this->assertEquals('#555555', $elementColor);
+ }
+
+ public function testGenerateRadioButtonWhite() {
+ $button = $this->util->generateRadioButton('#ffffff');
+ $expected = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZD0iTTggMWE3IDcgMCAwIDAtNyA3IDcgNyAwIDAgMCA3IDcgNyA3IDAgMCAwIDctNyA3IDcgMCAwIDAtNy03em0wIDFhNiA2IDAgMCAxIDYgNiA2IDYgMCAwIDEtNiA2IDYgNiAwIDAgMS02LTYgNiA2IDAgMCAxIDYtNnptMCAyYTQgNCAwIDEgMCAwIDggNCA0IDAgMCAwIDAtOHoiIGZpbGw9IiNmZmZmZmYiLz48L3N2Zz4=';
+ $this->assertEquals($expected, $button);
+ }
+ public function testGenerateRadioButtonBlack() {
+ $button = $this->util->generateRadioButton('#000000');
+ $expected = 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+PHBhdGggZD0iTTggMWE3IDcgMCAwIDAtNyA3IDcgNyAwIDAgMCA3IDcgNyA3IDAgMCAwIDctNyA3IDcgMCAwIDAtNy03em0wIDFhNiA2IDAgMCAxIDYgNiA2IDYgMCAwIDEtNiA2IDYgNiAwIDAgMS02LTYgNiA2IDAgMCAxIDYtNnptMCAyYTQgNCAwIDEgMCAwIDggNCA0IDAgMCAwIDAtOHoiIGZpbGw9IiMwMDAwMDAiLz48L3N2Zz4=';
+ $this->assertEquals($expected, $button);
+ }
+}
diff --git a/apps/theming/tests/lib/UtilTest.php b/apps/theming/tests/lib/UtilTest.php
deleted file mode 100644
index 9ebb11d6288..00000000000
--- a/apps/theming/tests/lib/UtilTest.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
- *
- * @author Julius Haertl <jus@bitgrid.net>
- *
- * @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\Theming\Tests;
-
-use OCA\Theming\Util;
-use Test\TestCase;
-
-class UtilTest extends TestCase {
-
- public function testInvertTextColorLight() {
- $invert = Util::invertTextColor('#ffffff');
- $this->assertEquals(true, $invert);
- }
-
- public function testInvertTextColorDark() {
- $invert = Util::invertTextColor('#000000');
- $this->assertEquals(false, $invert);
- }
-
- public function testCalculateLuminanceLight() {
- $luminance = Util::calculateLuminance('#ffffff');
- $this->assertEquals(1, $luminance);
- }
-
- public function testCalculateLuminanceDark() {
- $luminance = Util::calculateLuminance('#000000');
- $this->assertEquals(0, $luminance);
- }
-
- public function testCalculateLuminanceLightShorthand() {
- $luminance = Util::calculateLuminance('#fff');
- $this->assertEquals(1, $luminance);
- }
-
- public function testCalculateLuminanceDarkShorthand() {
- $luminance = Util::calculateLuminance('#000');
- $this->assertEquals(0, $luminance);
- }
- public function testInvertTextColorInvalid() {
- $invert = Util::invertTextColor('aaabbbcccddd123');
- $this->assertEquals(false, $invert);
- }
-
- public function testInvertTextColorEmpty() {
- $invert = Util::invertTextColor('');
- $this->assertEquals(false, $invert);
- }
-}
diff --git a/apps/updatenotification/l10n/is.js b/apps/updatenotification/l10n/is.js
index a2bd2757d97..c1961755c78 100644
--- a/apps/updatenotification/l10n/is.js
+++ b/apps/updatenotification/l10n/is.js
@@ -1,14 +1,18 @@
OC.L10N.register(
"updatenotification",
{
+ "Update notifications" : "Tilkynningar um uppfærslu",
"{version} is available. Get more information on how to update." : "{version} er í boði. Fáðu frekari upplýsingar um hvernig á að uppfæra.",
"Updated channel" : "Uppfærði rás",
+ "Nextcloud core" : "Nextcloud kjarni",
+ "Update for %1$s to version %2$s is available." : "Upfærsla %1$s í útgáfu %2$s er tiltæk.",
"Updater" : "Uppfærslustýring",
"A new version is available: %s" : "Ný útgáfa er tiltæk: %s",
"Open updater" : "Opna uppfærslustýringu",
"Your version is up to date." : "Útgáfan þín er af nýjustu gerð.",
"Checked on %s" : "Athugað þann %s",
"Update channel:" : "Uppfærslurás:",
- "You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel." : "Þú getur alltaf uppfært í nýrri útgáfu eða tilraunaútgáfurás. En þú getur aldrei niðurfært í stöðugri rás."
+ "You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel." : "Þú getur alltaf uppfært í nýrri útgáfu eða tilraunaútgáfurás. En þú getur aldrei niðurfært í stöðugri rás.",
+ "Notify members of the following groups about available updates:" : "Tilkynna meðlimum eftirfarandi hópa um tiltækar uppfærslur:"
},
"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);");
diff --git a/apps/updatenotification/l10n/is.json b/apps/updatenotification/l10n/is.json
index 45df407065f..044131460fc 100644
--- a/apps/updatenotification/l10n/is.json
+++ b/apps/updatenotification/l10n/is.json
@@ -1,12 +1,16 @@
{ "translations": {
+ "Update notifications" : "Tilkynningar um uppfærslu",
"{version} is available. Get more information on how to update." : "{version} er í boði. Fáðu frekari upplýsingar um hvernig á að uppfæra.",
"Updated channel" : "Uppfærði rás",
+ "Nextcloud core" : "Nextcloud kjarni",
+ "Update for %1$s to version %2$s is available." : "Upfærsla %1$s í útgáfu %2$s er tiltæk.",
"Updater" : "Uppfærslustýring",
"A new version is available: %s" : "Ný útgáfa er tiltæk: %s",
"Open updater" : "Opna uppfærslustýringu",
"Your version is up to date." : "Útgáfan þín er af nýjustu gerð.",
"Checked on %s" : "Athugað þann %s",
"Update channel:" : "Uppfærslurás:",
- "You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel." : "Þú getur alltaf uppfært í nýrri útgáfu eða tilraunaútgáfurás. En þú getur aldrei niðurfært í stöðugri rás."
+ "You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel." : "Þú getur alltaf uppfært í nýrri útgáfu eða tilraunaútgáfurás. En þú getur aldrei niðurfært í stöðugri rás.",
+ "Notify members of the following groups about available updates:" : "Tilkynna meðlimum eftirfarandi hópa um tiltækar uppfærslur:"
},"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"
} \ No newline at end of file
diff --git a/apps/user_ldap/ajax/wizard.php b/apps/user_ldap/ajax/wizard.php
index b5eab90af48..654fb70ced5 100644
--- a/apps/user_ldap/ajax/wizard.php
+++ b/apps/user_ldap/ajax/wizard.php
@@ -60,7 +60,7 @@ $userManager = new \OCA\User_LDAP\User\Manager(
\OC::$server->getDatabaseConnection(),
\OC::$server->getUserManager());
-$access = new \OCA\User_LDAP\Access($con, $ldapWrapper, $userManager);
+$access = new \OCA\User_LDAP\Access($con, $ldapWrapper, $userManager, new \OCA\User_LDAP\Helper());
$wizard = new \OCA\User_LDAP\Wizard($configuration, $ldapWrapper, $access);
diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 18987614bdb..10cc003a3f5 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -44,7 +44,7 @@ if(count($configPrefixes) === 1) {
\OC::$server->getUserManager()
);
$connector = new OCA\User_LDAP\Connection($ldapWrapper, $configPrefixes[0]);
- $ldapAccess = new OCA\User_LDAP\Access($connector, $ldapWrapper, $userManager);
+ $ldapAccess = new OCA\User_LDAP\Access($connector, $ldapWrapper, $userManager, $helper);
$ldapAccess->setUserMapper(new OCA\User_LDAP\Mapping\UserMapping($dbc));
$ldapAccess->setGroupMapper(new OCA\User_LDAP\Mapping\GroupMapping($dbc));
diff --git a/apps/user_ldap/appinfo/install.php b/apps/user_ldap/appinfo/install.php
index b3c92b0024a..c16a1f4a039 100644
--- a/apps/user_ldap/appinfo/install.php
+++ b/apps/user_ldap/appinfo/install.php
@@ -4,6 +4,7 @@
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
* @author Christopher Schäpers <kondou@ts.unde.re>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -24,3 +25,6 @@ $state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'doSet');
if($state === 'doSet') {
OCP\Config::setSystemValue('ldapIgnoreNamingRules', false);
}
+
+$helper = new \OCA\User_LDAP\Helper();
+$helper->setLDAPProvider();
diff --git a/apps/user_ldap/appinfo/update.php b/apps/user_ldap/appinfo/update.php
new file mode 100644
index 00000000000..3c9745338e6
--- /dev/null
+++ b/apps/user_ldap/appinfo/update.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
+ *
+ * @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/>.
+ *
+ */
+
+$helper = new \OCA\User_LDAP\Helper();
+$helper->setLDAPProvider();
diff --git a/apps/user_ldap/lib/Access.php b/apps/user_ldap/lib/Access.php
index dabf243eda1..299ad581644 100644
--- a/apps/user_ldap/lib/Access.php
+++ b/apps/user_ldap/lib/Access.php
@@ -20,6 +20,7 @@
* @author Ralph Krimmel <rkrimme1@gwdg.de>
* @author Renaud Fortier <Renaud.Fortier@fsaa.ulaval.ca>
* @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -77,13 +78,19 @@ class Access extends LDAPUtility implements IUserTools {
* @var AbstractMapping $userMapper
*/
protected $groupMapper;
+
+ /**
+ * @var \OCA\User_LDAP\Helper
+ */
+ private $helper;
public function __construct(Connection $connection, ILDAPWrapper $ldap,
- Manager $userManager) {
+ Manager $userManager, Helper $helper) {
parent::__construct($ldap);
$this->connection = $connection;
$this->userManager = $userManager;
$this->userManager->setLdapAccess($this);
+ $this->helper = $helper;
}
/**
@@ -173,7 +180,7 @@ class Access extends LDAPUtility implements IUserTools {
// (cf. #12306), 500 is default for paging and should work everywhere.
$maxResults = $pagingSize > 20 ? $pagingSize : 500;
$this->initPagedSearch($filter, array($dn), array($attr), $maxResults, 0);
- $dn = $this->DNasBaseParameter($dn);
+ $dn = $this->helper->DNasBaseParameter($dn);
$rr = @$this->ldap->read($cr, $dn, $filter, array($attr));
if(!$this->ldap->isResource($rr)) {
if(!empty($attr)) {
@@ -201,7 +208,7 @@ class Access extends LDAPUtility implements IUserTools {
$values = array();
for($i=0;$i<$result[$attr]['count'];$i++) {
if($this->resemblesDN($attr)) {
- $values[] = $this->sanitizeDN($result[$attr][$i]);
+ $values[] = $this->helper->sanitizeDN($result[$attr][$i]);
} elseif(strtolower($attr) === 'objectguid' || strtolower($attr) === 'guid') {
$values[] = $this->convertObjectGUID2Str($result[$attr][$i]);
} else {
@@ -243,49 +250,6 @@ class Access extends LDAPUtility implements IUserTools {
}
/**
- * sanitizes a DN received from the LDAP server
- * @param array $dn the DN in question
- * @return array the sanitized DN
- */
- private function sanitizeDN($dn) {
- //treating multiple base DNs
- if(is_array($dn)) {
- $result = array();
- foreach($dn as $singleDN) {
- $result[] = $this->sanitizeDN($singleDN);
- }
- return $result;
- }
-
- //OID sometimes gives back DNs with whitespace after the comma
- // a la "uid=foo, cn=bar, dn=..." We need to tackle this!
- $dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
-
- //make comparisons and everything work
- $dn = mb_strtolower($dn, 'UTF-8');
-
- //escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
- //to use the DN in search filters, \ needs to be escaped to \5c additionally
- //to use them in bases, we convert them back to simple backslashes in readAttribute()
- $replacements = array(
- '\,' => '\5c2C',
- '\=' => '\5c3D',
- '\+' => '\5c2B',
- '\<' => '\5c3C',
- '\>' => '\5c3E',
- '\;' => '\5c3B',
- '\"' => '\5c22',
- '\#' => '\5c23',
- '(' => '\28',
- ')' => '\29',
- '*' => '\2A',
- );
- $dn = str_replace(array_keys($replacements), array_values($replacements), $dn);
-
- return $dn;
- }
-
- /**
* returns a DN-string that is cleaned from not domain parts, e.g.
* cn=foo,cn=bar,dc=foobar,dc=server,dc=org
* becomes dc=foobar,dc=server,dc=org
@@ -1071,10 +1035,10 @@ class Access extends LDAPUtility implements IUserTools {
}
if($key !== 'dn') {
$selection[$i][$key] = $this->resemblesDN($key) ?
- $this->sanitizeDN($item[$key])
+ $this->helper->sanitizeDN($item[$key])
: $item[$key];
} else {
- $selection[$i][$key] = [$this->sanitizeDN($item[$key])];
+ $selection[$i][$key] = [$this->helper->sanitizeDN($item[$key])];
}
}
@@ -1298,7 +1262,7 @@ class Access extends LDAPUtility implements IUserTools {
* @return bool
*/
public function areCredentialsValid($name, $password) {
- $name = $this->DNasBaseParameter($name);
+ $name = $this->helper->DNasBaseParameter($name);
$testConnection = clone $this->connection;
$credentials = array(
'ldapAgentName' => $name,
@@ -1570,15 +1534,6 @@ class Access extends LDAPUtility implements IUserTools {
}
/**
- * converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
- * @param string $dn the DN
- * @return string
- */
- private function DNasBaseParameter($dn) {
- return str_ireplace('\\5c', '\\', $dn);
- }
-
- /**
* checks if the given DN is part of the given base DN(s)
* @param string $dn the DN
* @param string[] $bases array containing the allowed base DN or DNs
@@ -1586,7 +1541,7 @@ class Access extends LDAPUtility implements IUserTools {
*/
public function isDNPartOfBase($dn, $bases) {
$belongsToBase = false;
- $bases = $this->sanitizeDN($bases);
+ $bases = $this->helper->sanitizeDN($bases);
foreach($bases as $base) {
$belongsToBase = true;
diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php
index 7bd5e97e4f4..7fb26526195 100644
--- a/apps/user_ldap/lib/Connection.php
+++ b/apps/user_ldap/lib/Connection.php
@@ -11,6 +11,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
* @author Robin McCorkell <robin@mccorkell.me.uk>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -52,6 +53,8 @@ class Connection extends LDAPUtility {
private $configID;
private $configured = false;
private $hasPagedResultSupport = true;
+ //whether connection should be kept on __destruct
+ private $dontDestruct = false;
/**
* @var bool runtime flag that indicates whether supported primary groups are available
@@ -93,7 +96,7 @@ class Connection extends LDAPUtility {
}
public function __destruct() {
- if($this->ldap->isResource($this->ldapConnectionRes)) {
+ if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
@$this->ldap->unbind($this->ldapConnectionRes);
};
}
@@ -105,6 +108,7 @@ class Connection extends LDAPUtility {
$this->configuration = new Configuration($this->configPrefix,
!is_null($this->configID));
$this->ldapConnectionRes = null;
+ $this->dontDestruct = true;
}
/**
diff --git a/apps/user_ldap/lib/Helper.php b/apps/user_ldap/lib/Helper.php
index ccc1d2c0b44..90807a3c526 100644
--- a/apps/user_ldap/lib/Helper.php
+++ b/apps/user_ldap/lib/Helper.php
@@ -10,6 +10,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <pvince81@owncloud.com>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -183,6 +184,70 @@ class Helper {
return $domain;
}
+
+ /**
+ *
+ * Set the LDAPProvider in the config
+ *
+ */
+ public function setLDAPProvider() {
+ $current = \OC::$server->getConfig()->getSystemValue('ldapProviderFactory', null);
+ if(is_null($current)) {
+ \OC::$server->getConfig()->setSystemValue('ldapProviderFactory', '\\OCA\\User_LDAP\\LDAPProviderFactory');
+ }
+ }
+
+ /**
+ * sanitizes a DN received from the LDAP server
+ * @param array $dn the DN in question
+ * @return array the sanitized DN
+ */
+ public function sanitizeDN($dn) {
+ //treating multiple base DNs
+ if(is_array($dn)) {
+ $result = array();
+ foreach($dn as $singleDN) {
+ $result[] = $this->sanitizeDN($singleDN);
+ }
+ return $result;
+ }
+
+ //OID sometimes gives back DNs with whitespace after the comma
+ // a la "uid=foo, cn=bar, dn=..." We need to tackle this!
+ $dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
+
+ //make comparisons and everything work
+ $dn = mb_strtolower($dn, 'UTF-8');
+
+ //escape DN values according to RFC 2253 – this is already done by ldap_explode_dn
+ //to use the DN in search filters, \ needs to be escaped to \5c additionally
+ //to use them in bases, we convert them back to simple backslashes in readAttribute()
+ $replacements = array(
+ '\,' => '\5c2C',
+ '\=' => '\5c3D',
+ '\+' => '\5c2B',
+ '\<' => '\5c3C',
+ '\>' => '\5c3E',
+ '\;' => '\5c3B',
+ '\"' => '\5c22',
+ '\#' => '\5c23',
+ '(' => '\28',
+ ')' => '\29',
+ '*' => '\2A',
+ );
+ $dn = str_replace(array_keys($replacements), array_values($replacements), $dn);
+
+ return $dn;
+ }
+
+ /**
+ * converts a stored DN so it can be used as base parameter for LDAP queries, internally we store them for usage in LDAP filters
+ * @param string $dn the DN
+ * @return string
+ */
+ public function DNasBaseParameter($dn) {
+ return str_ireplace('\\5c', '\\', $dn);
+ }
/**
* listens to a hook thrown by server2server sharing and replaces the given
diff --git a/apps/user_ldap/lib/IUserLDAP.php b/apps/user_ldap/lib/IUserLDAP.php
new file mode 100644
index 00000000000..cb7d0138892
--- /dev/null
+++ b/apps/user_ldap/lib/IUserLDAP.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
+ *
+ * @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\User_LDAP;
+
+interface IUserLDAP {
+
+ //Functions used by LDAPProvider
+
+ /**
+ * Return access for LDAP interaction.
+ * @param string $uid
+ * @return Access instance of Access for LDAP interaction
+ */
+ public function getLDAPAccess($uid);
+
+ /**
+ * Return a new LDAP connection for the specified user.
+ * @param string $uid
+ * @return resource of the LDAP connection
+ */
+ public function getNewLDAPConnection($uid);
+
+ /**
+ * Return the username for the given LDAP DN, if available.
+ * @param string $dn
+ * @return string|false with the username
+ */
+ public function dn2UserName($dn);
+}
diff --git a/apps/user_ldap/lib/Jobs/UpdateGroups.php b/apps/user_ldap/lib/Jobs/UpdateGroups.php
index 91d40d58742..047b95a6d9b 100644
--- a/apps/user_ldap/lib/Jobs/UpdateGroups.php
+++ b/apps/user_ldap/lib/Jobs/UpdateGroups.php
@@ -188,7 +188,7 @@ class UpdateGroups extends \OC\BackgroundJob\TimedJob {
$dbc,
\OC::$server->getUserManager());
$connector = new Connection($ldapWrapper, $configPrefixes[0]);
- $ldapAccess = new Access($connector, $ldapWrapper, $userManager);
+ $ldapAccess = new Access($connector, $ldapWrapper, $userManager, $helper);
$groupMapper = new GroupMapping($dbc);
$userMapper = new UserMapping($dbc);
$ldapAccess->setGroupMapper($groupMapper);
diff --git a/apps/user_ldap/lib/LDAPProvider.php b/apps/user_ldap/lib/LDAPProvider.php
new file mode 100644
index 00000000000..5bd6a0fd08c
--- /dev/null
+++ b/apps/user_ldap/lib/LDAPProvider.php
@@ -0,0 +1,188 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
+ *
+ * @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\User_LDAP;
+
+use OCP\IUserBackend;
+use OCP\LDAP\ILDAPProvider;
+use OCP\LDAP\IDeletionFlagSupport;
+use OCP\IServerContainer;
+use OCA\User_LDAP\User\DeletedUsersIndex;
+use OCA\User_LDAP\Mapping\UserMapping;
+
+/**
+ * LDAP provider for pulic access to the LDAP backend.
+ */
+class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
+
+ private $backend;
+ private $logger;
+ private $helper;
+ private $deletedUsersIndex;
+
+ /**
+ * Create new LDAPProvider
+ * @param \OCP\IServerContainer $serverContainer
+ * @throws \Exception if user_ldap app was not enabled
+ */
+ public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) {
+ $this->logger = $serverContainer->getLogger();
+ $this->helper = $helper;
+ $this->deletedUsersIndex = $deletedUsersIndex;
+ foreach ($serverContainer->getUserManager()->getBackends() as $backend){
+ $this->logger->debug('instance '.get_class($backend).' backend.', ['app' => 'user_ldap']);
+ if ($backend instanceof IUserLDAP) {
+ $this->backend = $backend;
+ return;
+ }
+ }
+ throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled');
+ }
+
+ /**
+ * Translate an user id to LDAP DN
+ * @param string $uid user id
+ * @return string with the LDAP DN
+ * @throws \Exception if translation was unsuccessful
+ */
+ public function getUserDN($uid) {
+ if(!$this->backend->userExists($uid)){
+ throw new \Exception('User id not found in LDAP');
+ }
+ $result = $this->backend->getLDAPAccess($uid)->username2dn($uid);
+ if(!$result){
+ throw new \Exception('Translation to LDAP DN unsuccessful');
+ }
+ return $result;
+ }
+
+ /**
+ * Translate a LDAP DN to an internal user name. If there is no mapping between
+ * the DN and the user name, a new one will be created.
+ * @param string $dn LDAP DN
+ * @return string with the internal user name
+ * @throws \Exception if translation was unsuccessful
+ */
+ public function getUserName($dn) {
+ $result = $this->backend->dn2UserName($dn);
+ if(!$result){
+ throw new \Exception('Translation to internal user name unsuccessful');
+ }
+ return $result;
+ }
+
+ /**
+ * Convert a stored DN so it can be used as base parameter for LDAP queries.
+ * @param string $dn the DN in question
+ * @return string
+ */
+ public function DNasBaseParameter($dn) {
+ return $this->helper->DNasBaseParameter($dn);
+ }
+
+ /**
+ * Sanitize a DN received from the LDAP server.
+ * @param array $dn the DN in question
+ * @return array the sanitized DN
+ */
+ public function sanitizeDN($dn) {
+ return $this->helper->sanitizeDN($dn);
+ }
+
+ /**
+ * Return a new LDAP connection resource for the specified user.
+ * The connection must be closed manually.
+ * @param string $uid user id
+ * @return resource of the LDAP connection
+ * @throws \Exception if user id was not found in LDAP
+ */
+ public function getLDAPConnection($uid) {
+ if(!$this->backend->userExists($uid)){
+ throw new \Exception('User id not found in LDAP');
+ }
+ return $this->backend->getNewLDAPConnection($uid);
+ }
+
+ /**
+ * Get the LDAP base for users.
+ * @param string $uid user id
+ * @return string the base for users
+ * @throws \Exception if user id was not found in LDAP
+ */
+ public function getLDAPBaseUsers($uid) {
+ if(!$this->backend->userExists($uid)){
+ throw new \Exception('User id not found in LDAP');
+ }
+ return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users'];
+ }
+
+ /**
+ * Get the LDAP base for groups.
+ * @param string $uid user id
+ * @return string the base for groups
+ * @throws \Exception if user id was not found in LDAP
+ */
+ public function getLDAPBaseGroups($uid) {
+ if(!$this->backend->userExists($uid)){
+ throw new \Exception('User id not found in LDAP');
+ }
+ return $this->backend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups'];
+ }
+
+ /**
+ * Clear the cache if a cache is used, otherwise do nothing.
+ * @param string $uid user id
+ * @throws \Exception if user id was not found in LDAP
+ */
+ public function clearCache($uid) {
+ if(!$this->backend->userExists($uid)){
+ throw new \Exception('User id not found in LDAP');
+ }
+ $this->backend->getLDAPAccess($uid)->getConnection()->clearCache();
+ }
+
+ /**
+ * Check whether a LDAP DN exists
+ * @param string $dn LDAP DN
+ * @return bool whether the DN exists
+ */
+ public function dnExists($dn) {
+ $result = $this->backend->dn2UserName($dn);
+ return !$result ? false : true;
+ }
+
+ /**
+ * Flag record for deletion.
+ * @param string $uid user id
+ */
+ public function flagRecord($uid) {
+ $this->deletedUsersIndex->markUser($uid);
+ }
+
+ /**
+ * Unflag record for deletion.
+ * @param string $uid user id
+ */
+ public function unflagRecord($uid) {
+ //do nothing
+ }
+}
diff --git a/apps/user_ldap/lib/LDAPProviderFactory.php b/apps/user_ldap/lib/LDAPProviderFactory.php
new file mode 100644
index 00000000000..528af001037
--- /dev/null
+++ b/apps/user_ldap/lib/LDAPProviderFactory.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
+ *
+ * @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\User_LDAP;
+
+use OCP\LDAP\ILDAPProviderFactory;
+use OCP\IServerContainer;
+use OCA\User_LDAP\User\DeletedUsersIndex;
+use OCA\User_LDAP\Mapping\UserMapping;
+
+class LDAPProviderFactory implements ILDAPProviderFactory {
+ /**
+ * Server container
+ *
+ * @var IServerContainer
+ */
+ private $serverContainer;
+
+ /**
+ * Constructor for the LDAP provider factory
+ *
+ * @param IServerContainer $serverContainer server container
+ */
+ public function __construct(IServerContainer $serverContainer) {
+ $this->serverContainer = $serverContainer;
+ }
+
+ /**
+ * creates and returns an instance of the ILDAPProvider
+ *
+ * @return OCP\LDAP\ILDAPProvider
+ */
+ public function getLDAPProvider() {
+ $dbConnection = $this->serverContainer->getDatabaseConnection();
+ $userMapping = new UserMapping($dbConnection);
+ return new LDAPProvider($this->serverContainer, new Helper(),
+ new DeletedUsersIndex($this->serverContainer->getConfig(),
+ $dbConnection, $userMapping));
+ }
+}
diff --git a/apps/user_ldap/lib/Proxy.php b/apps/user_ldap/lib/Proxy.php
index 07cc1ea0e8c..db1c761656f 100644
--- a/apps/user_ldap/lib/Proxy.php
+++ b/apps/user_ldap/lib/Proxy.php
@@ -77,7 +77,7 @@ abstract class Proxy {
$userManager =
new Manager($ocConfig, $fs, $log, $avatarM, new \OCP\Image(), $db, $coreUserManager);
$connector = new Connection($this->ldap, $configPrefix);
- $access = new Access($connector, $this->ldap, $userManager);
+ $access = new Access($connector, $this->ldap, $userManager, new Helper());
$access->setUserMapper($userMap);
$access->setGroupMapper($groupMap);
self::$accesses[$configPrefix] = $access;
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index 56d881c5d5a..3d247663b3f 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -435,7 +435,10 @@ class User {
if(!is_null($email)) {
$user = $this->userManager->get($this->uid);
if (!is_null($user)) {
- $user->setEMailAddress($email);
+ $currentEmail = $user->getEMailAddress();
+ if ($currentEmail !== $email) {
+ $user->setEMailAddress($email);
+ }
}
}
}
diff --git a/apps/user_ldap/lib/User_LDAP.php b/apps/user_ldap/lib/User_LDAP.php
index a2a65bb8406..ce1aafc210e 100644
--- a/apps/user_ldap/lib/User_LDAP.php
+++ b/apps/user_ldap/lib/User_LDAP.php
@@ -15,6 +15,7 @@
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Tom Needham <tom@owncloud.com>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -39,7 +40,7 @@ use OCA\User_LDAP\User\OfflineUser;
use OCA\User_LDAP\User\User;
use OCP\IConfig;
-class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface {
+class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
/** @var string[] $homesToKill */
protected $homesToKill = array();
@@ -90,6 +91,16 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
return false;
}
}
+
+ /**
+ * returns the username for the given LDAP DN, if available
+ *
+ * @param string $dn
+ * @return string|false with the username
+ */
+ public function dn2UserName($dn) {
+ return $this->access->dn2username($dn);
+ }
/**
* returns an LDAP record based on a given login name
@@ -384,8 +395,14 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
}
$user = $this->access->userManager->get($uid);
- $displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
- $this->access->connection->writeToCache($cacheKey, $displayName);
+ if ($user instanceof User) {
+ $displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
+ $this->access->connection->writeToCache($cacheKey, $displayName);
+ }
+ if ($user instanceof OfflineUser) {
+ /** @var OfflineUser $user*/
+ $displayName = $user->getDisplayName();
+ }
return $displayName;
}
@@ -462,5 +479,25 @@ class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn
public function getBackendName(){
return 'LDAP';
}
-
+
+ /**
+ * Return access for LDAP interaction.
+ * @param string $uid
+ * @return Access instance of Access for LDAP interaction
+ */
+ public function getLDAPAccess($uid) {
+ return $this->access;
+ }
+
+ /**
+ * Return LDAP connection resource from a cloned connection.
+ * The cloned connection needs to be closed manually.
+ * of the current access.
+ * @param string $uid
+ * @return resource of the LDAP connection
+ */
+ public function getNewLDAPConnection($uid) {
+ $connection = clone $this->access->getConnection();
+ return $connection->getConnectionResource();
+ }
}
diff --git a/apps/user_ldap/lib/User_Proxy.php b/apps/user_ldap/lib/User_Proxy.php
index c86d4f29ec4..cced469a7ae 100644
--- a/apps/user_ldap/lib/User_Proxy.php
+++ b/apps/user_ldap/lib/User_Proxy.php
@@ -9,6 +9,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Roger Szabo <roger.szabo@web.de>
*
* @license AGPL-3.0
*
@@ -31,7 +32,7 @@ namespace OCA\User_LDAP;
use OCA\User_LDAP\User\User;
use OCP\IConfig;
-class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface {
+class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
private $backends = array();
private $refBackend = null;
@@ -193,6 +194,17 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface
$id = 'LOGINNAME,' . $loginName;
return $this->handleRequest($id, 'loginName2UserName', array($loginName));
}
+
+ /**
+ * returns the username for the given LDAP DN, if available
+ *
+ * @param string $dn
+ * @return string|false with the username
+ */
+ public function dn2UserName($dn) {
+ $id = 'DN,' . $dn;
+ return $this->handleRequest($id, 'dn2UserName', array($dn));
+ }
/**
* get the user's home directory
@@ -273,4 +285,22 @@ class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface
return $users;
}
+ /**
+ * Return access for LDAP interaction.
+ * @param string $uid
+ * @return Access instance of Access for LDAP interaction
+ */
+ public function getLDAPAccess($uid) {
+ return $this->handleRequest($uid, 'getLDAPAccess', array($uid));
+ }
+
+ /**
+ * Return a new LDAP connection for the specified user.
+ * The connection needs to be closed manually.
+ * @param string $uid
+ * @return resource of the LDAP connection
+ */
+ public function getNewLDAPConnection($uid) {
+ return $this->handleRequest($uid, 'getNewLDAPConnection', array($uid));
+ }
}
diff --git a/apps/user_ldap/tests/AccessTest.php b/apps/user_ldap/tests/AccessTest.php
index f96813ba711..2fddafa214b 100644
--- a/apps/user_ldap/tests/AccessTest.php
+++ b/apps/user_ldap/tests/AccessTest.php
@@ -60,21 +60,22 @@ class AccessTest extends \Test\TestCase {
$this->getMock('\OCP\Image'),
$this->getMock('\OCP\IDBConnection'),
$this->getMock('\OCP\IUserManager')));
+ $helper = new \OCA\User_LDAP\Helper();
- return array($lw, $connector, $um);
+ return array($lw, $connector, $um, $helper);
}
public function testEscapeFilterPartValidChars() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$input = 'okay';
$this->assertTrue($input === $access->escapeFilterPart($input));
}
public function testEscapeFilterPartEscapeWildcard() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$input = '*';
$expected = '\\\\*';
@@ -82,8 +83,8 @@ class AccessTest extends \Test\TestCase {
}
public function testEscapeFilterPartEscapeWildcard2() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$input = 'foo*bar';
$expected = 'foo\\\\*bar';
@@ -92,8 +93,8 @@ class AccessTest extends \Test\TestCase {
/** @dataProvider convertSID2StrSuccessData */
public function testConvertSID2StrSuccess(array $sidArray, $sidExpected) {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$sidBinary = implode('', $sidArray);
$this->assertSame($sidExpected, $access->convertSID2Str($sidBinary));
@@ -127,8 +128,8 @@ class AccessTest extends \Test\TestCase {
}
public function testConvertSID2StrInputError() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$sidIllegal = 'foobar';
$sidExpected = '';
@@ -137,8 +138,8 @@ class AccessTest extends \Test\TestCase {
}
public function testGetDomainDNFromDNSuccess() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$inputDN = 'uid=zaphod,cn=foobar,dc=my,dc=server,dc=com';
$domainDN = 'dc=my,dc=server,dc=com';
@@ -152,8 +153,8 @@ class AccessTest extends \Test\TestCase {
}
public function testGetDomainDNFromDNError() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$inputDN = 'foobar';
$expected = '';
@@ -187,8 +188,8 @@ class AccessTest extends \Test\TestCase {
}
public function testStringResemblesDN() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$cases = $this->getResemblesDNInputData();
@@ -208,9 +209,9 @@ class AccessTest extends \Test\TestCase {
}
public function testStringResemblesDNLDAPmod() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
$lw = new \OCA\User_LDAP\LDAP();
- $access = new Access($con, $lw, $um);
+ $access = new Access($con, $lw, $um, $helper);
if(!function_exists('ldap_explode_dn')) {
$this->markTestSkipped('LDAP Module not available');
@@ -224,8 +225,8 @@ class AccessTest extends \Test\TestCase {
}
public function testCacheUserHome() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$con->expects($this->once())
->method('writeToCache');
@@ -234,8 +235,8 @@ class AccessTest extends \Test\TestCase {
}
public function testBatchApplyUserAttributes() {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
- $access = new Access($con, $lw, $um);
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
+ $access = new Access($con, $lw, $um, $helper);
$mapperMock = $this->getMockBuilder('\OCA\User_LDAP\Mapping\UserMapping')
->disableOriginalConstructor()
->getMock();
@@ -294,7 +295,7 @@ class AccessTest extends \Test\TestCase {
* @dataProvider dNAttributeProvider
*/
public function testSanitizeDN($attribute) {
- list($lw, $con, $um) = $this->getConnectorAndLdapMock();
+ list($lw, $con, $um, $helper) = $this->getConnectorAndLdapMock();
$dnFromServer = 'cn=Mixed Cases,ou=Are Sufficient To,ou=Test,dc=example,dc=org';
@@ -309,7 +310,7 @@ class AccessTest extends \Test\TestCase {
$attribute => array('count' => 1, $dnFromServer)
)));
- $access = new Access($con, $lw, $um);
+ $access = new Access($con, $lw, $um, $helper);
$values = $access->readAttribute('uid=whoever,dc=example,dc=org', $attribute);
$this->assertSame($values[0], strtolower($dnFromServer));
}
diff --git a/apps/user_ldap/tests/Group_LDAPTest.php b/apps/user_ldap/tests/Group_LDAPTest.php
index 71120bdb838..83ec2dedf22 100644
--- a/apps/user_ldap/tests/Group_LDAPTest.php
+++ b/apps/user_ldap/tests/Group_LDAPTest.php
@@ -55,9 +55,10 @@ class Group_LDAPTest extends \Test\TestCase {
$um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager')
->disableOriginalConstructor()
->getMock();
+ $helper = new \OCA\User_LDAP\Helper();
$access = $this->getMock('\OCA\User_LDAP\Access',
$accMethods,
- array($connector, $lw, $um));
+ array($connector, $lw, $um, $helper));
$access->expects($this->any())
->method('getConnection')
diff --git a/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php b/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php
index 4ec36617c14..bd56494eac0 100644
--- a/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php
+++ b/apps/user_ldap/tests/Integration/AbstractIntegrationTest.php
@@ -26,6 +26,7 @@ namespace OCA\User_LDAP\Tests\Integration;
use OCA\User_LDAP\Access;
use OCA\User_LDAP\Connection;
use OCA\User_LDAP\LDAP;
+use OCA\User_LDAP\Helper;
use OCA\User_LDAP\User\Manager;
abstract class AbstractIntegrationTest {
@@ -40,6 +41,9 @@ abstract class AbstractIntegrationTest {
/** @var Manager */
protected $userManager;
+
+ /** @var Helper */
+ protected $helper;
/** @var string */
protected $base;
@@ -65,6 +69,7 @@ abstract class AbstractIntegrationTest {
$this->initLDAPWrapper();
$this->initConnection();
$this->initUserManager();
+ $this->initHelper();
$this->initAccess();
}
@@ -103,12 +108,19 @@ abstract class AbstractIntegrationTest {
protected function initUserManager() {
$this->userManager = new FakeManager();
}
+
+ /**
+ * initializes the test Helper
+ */
+ protected function initHelper() {
+ $this->helper = new Helper();
+ }
/**
* initializes the Access test instance
*/
protected function initAccess() {
- $this->access = new Access($this->connection, $this->ldap, $this->userManager);
+ $this->access = new Access($this->connection, $this->ldap, $this->userManager, $this->helper);
}
/**
diff --git a/apps/user_ldap/tests/LDAPProviderTest.php b/apps/user_ldap/tests/LDAPProviderTest.php
new file mode 100644
index 00000000000..22dfb61e5fb
--- /dev/null
+++ b/apps/user_ldap/tests/LDAPProviderTest.php
@@ -0,0 +1,338 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2016, Roger Szabo (roger.szabo@web.de)
+ *
+ * @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\User_LDAP\Tests;
+
+use OCP\IServerContainer;
+use OCA\User_LDAP\IUserLDAP;
+
+/**
+ * Class LDAPProviderTest
+ *
+ * @group DB
+ *
+ * @package OCA\User_LDAP\Tests
+ */
+class LDAPProviderTest extends \Test\TestCase {
+
+ protected function setUp() {
+ parent::setUp();
+ }
+
+ private function getServerMock(IUserLDAP $backend) {
+ $server = $this->getMockBuilder('OC\Server')
+ ->setMethods(['getUserManager', 'getBackends'])
+ ->setConstructorArgs(['', new \OC\Config(\OC::$configDir)])
+ ->getMock();
+ $server->expects($this->at(1))
+ ->method('getBackends')
+ ->willReturn([$backend]);
+ $server->expects($this->any())
+ ->method($this->anything())
+ ->willReturnSelf();
+
+ return $server;
+ }
+
+ private function getLDAPProvider(IServerContainer $serverContainer) {
+ $factory = new \OCA\User_LDAP\LDAPProviderFactory($serverContainer);
+ return $factory->getLDAPProvider();
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage User id not found in LDAP
+ */
+ public function testGetUserDNUserIDNotFound() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())->method('userExists')->willReturn(false);
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->getUserDN('nonexisting_user');
+ }
+
+ public function testGetUserDN() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists', 'getLDAPAccess', 'username2dn'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->at(0))
+ ->method('userExists')
+ ->willReturn(true);
+ $backend->expects($this->at(2))
+ ->method('username2dn')
+ ->willReturn('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org');
+ $backend->expects($this->any())
+ ->method($this->anything())
+ ->willReturnSelf();
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertEquals('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org',
+ $ldapProvider->getUserDN('existing_user'));
+ }
+
+ public function testGetUserName() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['dn2UserName'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())
+ ->method('dn2UserName')
+ ->willReturn('existing_user');
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertEquals('existing_user',
+ $ldapProvider->getUserName('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+ }
+
+ public function testDNasBaseParameter() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods([])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $server = $this->getServerMock($backend);
+
+ $helper = new \OCA\User_LDAP\Helper();
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertEquals(
+ $helper->DNasBaseParameter('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'),
+ $ldapProvider->DNasBaseParameter('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+ }
+
+ public function testSanitizeDN() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods([])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $server = $this->getServerMock($backend);
+
+ $helper = new \OCA\User_LDAP\Helper();
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertEquals(
+ $helper->sanitizeDN('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'),
+ $ldapProvider->sanitizeDN('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage User id not found in LDAP
+ */
+ public function testGetLDAPConnectionUserIDNotFound() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())->method('userExists')->willReturn(false);
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->getLDAPConnection('nonexisting_user');
+ }
+
+ public function testGetLDAPConnection() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists', 'getNewLDAPConnection'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())
+ ->method('userExists')
+ ->willReturn(true);
+ $backend->expects($this->any())
+ ->method('getNewLDAPConnection')
+ ->willReturn(true);
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertTrue($ldapProvider->getLDAPConnection('existing_user'));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage User id not found in LDAP
+ */
+ public function testGetLDAPBaseUsersUserIDNotFound() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())->method('userExists')->willReturn(false);
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->getLDAPBaseUsers('nonexisting_user');
+ }
+
+ public function testGetLDAPBaseUsers() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->at(0))
+ ->method('userExists')
+ ->willReturn(true);
+ $backend->expects($this->at(3))
+ ->method('getConfiguration')
+ ->willReturn(array('ldap_base_users'=>'ou=users,dc=example,dc=org'));
+ $backend->expects($this->any())
+ ->method($this->anything())
+ ->willReturnSelf();
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertEquals('ou=users,dc=example,dc=org', $ldapProvider->getLDAPBaseUsers('existing_user'));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage User id not found in LDAP
+ */
+ public function testGetLDAPBaseGroupsUserIDNotFound() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())->method('userExists')->willReturn(false);
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->getLDAPBaseGroups('nonexisting_user');
+ }
+
+ public function testGetLDAPBaseGroups() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'getConfiguration'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->at(0))
+ ->method('userExists')
+ ->willReturn(true);
+ $backend->expects($this->at(3))
+ ->method('getConfiguration')
+ ->willReturn(array('ldap_base_groups'=>'ou=groups,dc=example,dc=org'));
+ $backend->expects($this->any())
+ ->method($this->anything())
+ ->willReturnSelf();
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertEquals('ou=groups,dc=example,dc=org', $ldapProvider->getLDAPBaseGroups('existing_user'));
+ }
+
+ /**
+ * @expectedException \Exception
+ * @expectedExceptionMessage User id not found in LDAP
+ */
+ public function testClearCacheUserIDNotFound() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())->method('userExists')->willReturn(false);
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->clearCache('nonexisting_user');
+ }
+
+ public function testClearCache() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['userExists', 'getLDAPAccess', 'getConnection', 'clearCache'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->at(0))
+ ->method('userExists')
+ ->willReturn(true);
+ $backend->expects($this->at(3))
+ ->method('clearCache')
+ ->willReturn(true);
+ $backend->expects($this->any())
+ ->method($this->anything())
+ ->willReturnSelf();
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->clearCache('existing_user');
+ $this->assertTrue(TRUE);
+ }
+
+ public function testDnExists() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods(['dn2UserName'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $backend->expects($this->any())
+ ->method('dn2UserName')
+ ->willReturn('existing_user');
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $this->assertTrue($ldapProvider->dnExists('cn=existing_user,ou=Are Sufficient To,ou=Test,dc=example,dc=org'));
+ }
+
+ public function testFlagRecord() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods([])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->flagRecord('existing_user');
+ $this->assertTrue(TRUE);
+ }
+
+ public function testUnflagRecord() {
+ $backend = $this->getMockBuilder('OCA\User_LDAP\User_LDAP')
+ ->setMethods([])
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $server = $this->getServerMock($backend);
+
+ $ldapProvider = $this->getLDAPProvider($server);
+ $ldapProvider->unflagRecord('existing_user');
+ $this->assertTrue(TRUE);
+ }
+}
diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php
index cf1514009d8..d9e43dee047 100644
--- a/apps/user_ldap/tests/User/UserTest.php
+++ b/apps/user_ldap/tests/User/UserTest.php
@@ -71,8 +71,9 @@ class UserTest extends \Test\TestCase {
$umMethods, array($cfMock, $fsMock, $logMock, $avaMgr, $im, $dbc, $userMgr));
$connector = $this->getMock('\OCA\User_LDAP\Connection',
$conMethods, array($lw, null, null));
+ $helper = new \OCA\User_LDAP\Helper();
$access = $this->getMock('\OCA\User_LDAP\Access',
- $accMethods, array($connector, $lw, $um));
+ $accMethods, array($connector, $lw, $um, $helper));
return array($access, $connector);
}
diff --git a/apps/user_ldap/tests/User_LDAPTest.php b/apps/user_ldap/tests/User_LDAPTest.php
index ae86e3cf3a2..47e789142e5 100644
--- a/apps/user_ldap/tests/User_LDAPTest.php
+++ b/apps/user_ldap/tests/User_LDAPTest.php
@@ -93,9 +93,11 @@ class User_LDAPTest extends \Test\TestCase {
->method('getDeletedUser')
->will($this->returnValue($offlineUser));
+ $helper = new \OCA\User_LDAP\Helper();
+
$access = $this->getMock('\OCA\User_LDAP\Access',
$accMethods,
- array($connector, $lw, $um));
+ array($connector, $lw, $um, $helper));
$um->setLdapAccess($access);
diff --git a/apps/user_ldap/tests/WizardTest.php b/apps/user_ldap/tests/WizardTest.php
index cc110c6ee0d..e82cbcfc82a 100644
--- a/apps/user_ldap/tests/WizardTest.php
+++ b/apps/user_ldap/tests/WizardTest.php
@@ -69,8 +69,9 @@ class WizardTest extends \Test\TestCase {
$um = $this->getMockBuilder('\OCA\User_LDAP\User\Manager')
->disableOriginalConstructor()
->getMock();
+ $helper = new \OCA\User_LDAP\Helper();
$access = $this->getMock('\OCA\User_LDAP\Access',
- $accMethods, array($connector, $lw, $um));
+ $accMethods, array($connector, $lw, $um, $helper));
return array(new Wizard($conf, $lw, $access), $conf, $lw, $access);
}
diff --git a/apps/workflowengine/lib/Check/UserGroupMembership.php b/apps/workflowengine/lib/Check/UserGroupMembership.php
index f437dbfc2d1..6390c57fbea 100644
--- a/apps/workflowengine/lib/Check/UserGroupMembership.php
+++ b/apps/workflowengine/lib/Check/UserGroupMembership.php
@@ -24,6 +24,7 @@ namespace OCA\WorkflowEngine\Check;
use OCP\Files\Storage\IStorage;
use OCP\IGroupManager;
+use OCP\IL10N;
use OCP\IUser;
use OCP\IUserSession;
use OCP\WorkflowEngine\ICheck;
@@ -42,13 +43,18 @@ class UserGroupMembership implements ICheck {
/** @var IGroupManager */
protected $groupManager;
+ /** @var IL10N */
+ protected $l;
+
/**
* @param IUserSession $userSession
* @param IGroupManager $groupManager
+ * @param IL10N $l
*/
- public function __construct(IUserSession $userSession, IGroupManager $groupManager) {
+ public function __construct(IUserSession $userSession, IGroupManager $groupManager, IL10N $l) {
$this->userSession = $userSession;
$this->groupManager = $groupManager;
+ $this->l = $l;
}
/**
@@ -83,11 +89,11 @@ class UserGroupMembership implements ICheck {
*/
public function validateCheck($operator, $value) {
if (!in_array($operator, ['is', '!is'])) {
- throw new \UnexpectedValueException('Invalid operator', 1);
+ throw new \UnexpectedValueException($this->l->t('Operator %s is invalid', $operator), 1);
}
if (!$this->groupManager->groupExists($value)) {
- throw new \UnexpectedValueException('Group does not exist', 2);
+ throw new \UnexpectedValueException($this->l->t('Group %s does not exist', $value), 2);
}
}
diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php
index f2a04dfb0fa..b72836a919c 100644
--- a/apps/workflowengine/lib/Manager.php
+++ b/apps/workflowengine/lib/Manager.php
@@ -26,6 +26,7 @@ use OCP\AppFramework\QueryException;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\Storage\IStorage;
use OCP\IDBConnection;
+use OCP\IL10N;
use OCP\IServerContainer;
use OCP\WorkflowEngine\ICheck;
use OCP\WorkflowEngine\IManager;
@@ -50,13 +51,18 @@ class Manager implements IManager {
/** @var IServerContainer|\OC\Server */
protected $container;
+ /** @var IL10N */
+ protected $l;
+
/**
* @param IDBConnection $connection
* @param IServerContainer $container
+ * @param IL10N $l
*/
- public function __construct(IDBConnection $connection, IServerContainer $container) {
+ public function __construct(IDBConnection $connection, IServerContainer $container, IL10N $l) {
$this->connection = $connection;
$this->container = $container;
+ $this->l = $l;
}
/**
@@ -111,7 +117,7 @@ class Manager implements IManager {
return $checkInstance->executeCheck($check['operator'], $check['value']);
} else {
// Check is invalid
- throw new \RuntimeException('Check ' . htmlspecialchars($check['class']) . ' is invalid or does not exist');
+ throw new \UnexpectedValueException($this->l->t('Check %s is invalid or does not exist', $check['class']));
}
}
@@ -158,7 +164,7 @@ class Manager implements IManager {
return $row;
}
- throw new \UnexpectedValueException('Operation does not exist');
+ throw new \UnexpectedValueException($this->l->t('Operation #%s does not exist', $id));
}
/**
@@ -262,7 +268,7 @@ class Manager implements IManager {
if (!empty($checkIds)) {
$missingCheck = array_pop($checkIds);
- throw new \RuntimeException('Check #' . htmlspecialchars($missingCheck) . ' is invalid or does not exist');
+ throw new \UnexpectedValueException($this->l->t('Check #%s does not exist', $missingCheck));
}
return $checks;
diff --git a/apps/workflowengine/templates/admin.php b/apps/workflowengine/templates/admin.php
index 9e01f8359fa..4eabf783bba 100644
--- a/apps/workflowengine/templates/admin.php
+++ b/apps/workflowengine/templates/admin.php
@@ -20,13 +20,13 @@
*/
/** @var array $_ */
-/** @var OC_L10N $l */
+/** @var \OCP\IL10N $l */
?>
<div id="<?php p($_['appid']); ?>" class="section workflowengine">
<h2 class="inlineblock"><?php p($_['heading']); ?></h2>
<script type="text/template" id="operations-template">
<div class="operations"></div>
- <button class="button-add-operation">Add operation</button>
+ <button class="button-add-operation"><?php p($l->t('Add operation')); ?></button>
</script>
<script type="text/template" id="operation-template">
@@ -56,17 +56,17 @@
</div>
{{/each}}
</div>
- <button class="button-add">Add check</button>
+ <button class="button-add"><?php p($l->t('Add check')); ?></button>
{{#if hasChanged}}
{{! reset only makes sense if the operation is already saved }}
{{#if operation.id}}
- <button class="button-reset pull-right">Reset</button>
+ <button class="button-reset pull-right"><?php p($l->t('Reset')); ?></button>
{{/if}}
- <button class="button-save pull-right">Save</button>
+ <button class="button-save pull-right"><?php p($l->t('Save')); ?></button>
{{/if}}
{{#if saving}}
<span class="icon-loading-small pull-right"></span>
- <span class="pull-right">Saving ...</span>
+ <span class="pull-right"><?php p($l->t('Saving…')); ?></span>
{{else}}{{#if message}}
<span class="msg pull-right {{#if errorMessage}}error{{else}}success{{/if}}">
{{message}}{{#if errorMessage}} {{errorMessage}}{{/if}}
@@ -75,5 +75,5 @@
</div>
</script>
- <div class="rules"><span class="icon-loading-small"></span> Loading ...</div>
+ <div class="rules"><span class="icon-loading-small"></span> <?php p($l->t('Loading…')); ?></div>
</div>