Merge remote-tracking branch 'origin/master' into users-management-enhancements

This commit is contained in:
Roeland Jago Douma 2019-02-25 21:48:41 +01:00
commit c7aa20eaec
No known key found for this signature in database
GPG Key ID: F941078878347C0C
163 changed files with 3502 additions and 1558 deletions

View File

@ -529,7 +529,6 @@ pipeline:
image: nextcloudci/integration-php7.1:1
commands:
- ./occ maintenance:install --admin-pass=admin --data-dir=/dev/shm/nc_int
- ./occ app:enable user_ldap
- cd build/integration
- ./run.sh ldap_features/ldap-ocs.feature
when:
@ -544,7 +543,6 @@ pipeline:
- ./occ config:system:set redis timeout --value=0 --type=integer
- ./occ config:system:set --type string --value "\\OC\\Memcache\\Redis" memcache.local
- ./occ config:system:set --type string --value "\\OC\\Memcache\\Redis" memcache.distributed
- ./occ app:enable user_ldap
- cd build/integration
- ./run.sh ldap_features/ldap-openldap.feature
when:
@ -559,7 +557,6 @@ pipeline:
- ./occ config:system:set redis timeout --value=0 --type=integer
- ./occ config:system:set --type string --value "\\OC\\Memcache\\Redis" memcache.local
- ./occ config:system:set --type string --value "\\OC\\Memcache\\Redis" memcache.distributed
- ./occ app:enable user_ldap
- cd build/integration
- ./run.sh ldap_features/openldap-uid-username.feature
when:
@ -574,7 +571,6 @@ pipeline:
- ./occ config:system:set redis timeout --value=0 --type=integer
- ./occ config:system:set --type string --value "\\OC\\Memcache\\Redis" memcache.local
- ./occ config:system:set --type string --value "\\OC\\Memcache\\Redis" memcache.distributed
- ./occ app:enable user_ldap
- cd build/integration
- ./run.sh ldap_features/openldap-numerical-id.feature
when:

@ -1 +1 @@
Subproject commit 7c64d231f833b8ab8f9dcd017499c8c18b7b78f9
Subproject commit 3421f64a4312dc7a48a82cce9becd2cdf888caa4

View File

@ -1,6 +1,6 @@
all: dev-setup build-js-production
dev-setup: clean clean-dev npm-init
dev-setup: clean-dev npm-init
npm-init:
npm install
@ -17,10 +17,6 @@ build-js-production:
watch-js:
npm run watch
clean:
rm -f js/vue-*.js
rm -f js/vue-*.js.map
clean-dev:
rm -rf node_modules

View File

@ -61,7 +61,7 @@ Otherwise, git checkouts can be handled the same as release archives, by using t
### Building front-end code 🏗
We move more and more towards using Vue.js in the frontend, starting with Settings. For building the code on changes, use these terminal commands in the `settings` subfolder:
We move more and more towards using Vue.js in the frontend, starting with Settings. For building the code on changes, use these terminal commands in the root folder:
``` bash
# install dependencies
@ -75,9 +75,6 @@ make watch-js
# build for production with minification
make build-js-production
# clean output files
make clean
```
**When making changes, also commit the compiled files!**

View File

@ -1,59 +1,63 @@
// Rules we could port to the rest of Nextcloud too
// Proper highlight for links and focus feedback
#accessibility a {
font-weight: bold;
&:hover,
&:focus {
text-decoration: underline;
}
}
// Highlight checkbox label in bold for focus feedback
// Drawback: Text width increases a bit
#accessibility .checkbox:focus + label {
font-weight: bold;
}
// Limit width of settings sections for readability
#accessibility.section p {
max-width: 800px;
}
// End of rules we could port to rest of Nextcloud
.preview-list {
display: flex;
flex-wrap: wrap;
flex-direction: column;
max-width: 800px;
}
.preview {
display: flex;
flex-direction: column;
min-width: 250px;
max-width: 400px;
flex: 1 1 300px;
border: 1px solid var(--color-border);
padding: 10px;
border-radius: var(--border-radius);
transition: all 200ms ease-in-out;
filter: drop-shadow(0 1px 2px var(--color-box-shadow));
background-color: var(--color-main-background);
opacity: 0.9;
margin: 10px;
justify-content: flex-start;
margin-top: 3em;
position: relative;
&,
* {
cursor: pointer;
user-select: none;
}
&:hover,
&:focus,
&.selected {
filter: drop-shadow(0 1px 4px var(--color-box-shadow));
opacity: 1;
}
.preview-image {
height: 200px;
flex-basis: 200px;
flex-shrink: 0;
margin-right: 1em;
background-position: top left;
background-size: cover;
background-repeat: no-repeat;
border-radius: var(--border-radius);
}
h3 {
.preview-description {
display: flex;
justify-content: space-between;
line-height: 1em;
align-items: center;
}
p {
text-align: justify;
}
.icon-checkmark-color {
transition: all 100ms ease-in-out;
border-radius: 1em;
padding: 4px 5px 4px 20px;
background-position: 4px center;
opacity: 0;
visibility: hidden;
}
&.selected .icon-checkmark-color {
opacity: 1;
visibility: visible;
box-shadow: 0 0 0 1px var(--color-success);
flex-direction: column;
label {
padding: 12px 0;
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -75,7 +75,7 @@ class AccessibilityProvider {
'id' => 'fontdyslexic',
'img' => $this->urlGenerator->imagePath($this->appName, 'font-opendyslexic.jpg'),
'title' => $this->l->t('Dyslexia font'),
'text' => $this->l->t('OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia. The typeface was created by Abelardo Gonzalez, who released it through an open-source license.')
'text' => $this->l->t('OpenDyslexic is a free typeface/font designed to mitigate some of the common reading errors caused by dyslexia.')
]
);
}

View File

@ -1,20 +1,16 @@
<template>
<div id="accessibility">
<div id="themes" class="section">
<h2>{{t('accessibility', 'Themes')}}</h2>
<div class="themes-list preview-list">
<preview v-for="preview in themes" :preview="preview"
:key="preview.id" :selected="selected.theme"
v-on:select="selectTheme"></preview>
</div>
</div>
<div id="fonts" class="section">
<h2>{{t('accessibility', 'Fonts')}}</h2>
<div class="fonts-list preview-list">
<preview v-for="preview in fonts" :preview="preview"
:key="preview.id" :selected="selected.font"
v-on:select="selectFont"></preview>
</div>
<div id="accessibility" class="section">
<h2>{{t('accessibility', 'Accessibility')}}</h2>
<p v-html="description" />
<p v-html="descriptionDetail" />
<div class="preview-list">
<preview v-for="preview in themes" :preview="preview"
:key="preview.id" :selected="selected.theme"
v-on:select="selectTheme"></preview>
<preview v-for="preview in fonts" :preview="preview"
:key="preview.id" :selected="selected.font"
v-on:select="selectFont"></preview>
</div>
</div>
</template>
@ -52,6 +48,36 @@ export default {
theme: this.serverData.theme,
font: this.serverData.font
};
},
description() {
// using the `t` replace method escape html, we have to do it manually :/
return t(
'accessibility',
`Universal access is very important to us. We follow web standards
and check to make everything usable also without mouse,
and assistive software such as screenreaders.
We aim to be compliant with the {guidelines} 2.1 on AA level,
with the high contrast theme even on AAA level.`
)
.replace('{guidelines}', this.guidelinesLink)
},
guidelinesLink() {
return `<a target="_blank" href="https://www.w3.org/WAI/standards-guidelines/wcag/" rel="noreferrer nofollow">${t('accessibility', 'Web Content Accessibility Guidelines')}</a>`
},
descriptionDetail() {
return t(
'accessibility',
`If you find any issues, dont hesitate to report them on {issuetracker}.
And if you want to get involved, come join {designteam}!`
)
.replace('{issuetracker}', this.issuetrackerLink)
.replace('{designteam}', this.designteamLink)
},
issuetrackerLink() {
return `<a target="_blank" href="https://github.com/nextcloud/server/issues/" rel="noreferrer nofollow">${t('accessibility', 'our issue tracker')}</a>`
},
designteamLink() {
return `<a target="_blank" href="https://nextcloud.com/design" rel="noreferrer nofollow">${t('accessibility', 'our design team')}</a>`
}
},
methods: {

View File

@ -1,13 +1,13 @@
<template>
<a :class="{preview: true, selected: preview.id === selected}"
href="#" @click="selectItem">
<div :class="{preview: true}">
<div class="preview-image" :style="{backgroundImage: 'url(' + preview.img + ')'}"></div>
<h3>
<span>{{preview.title}}</span>
<div class="icon-checkmark-color">{{t('accessibility', 'enabled')}}</div>
</h3>
<p>{{preview.text}}</p>
</a>
<div class="preview-description">
<h3>{{preview.title}}</h3>
<p>{{preview.text}}</p>
<input type="checkbox" class="checkbox" :id="'accessibility-' + preview.id" :checked="selected === preview.id" />
<label :for="'accessibility-' + preview.id" @click="selectItem">{{t('accessibility', 'Enable')}} {{preview.title.toLowerCase()}}</label>
</div>
</div>
</template>
<script>

View File

@ -30,7 +30,7 @@ class Console extends Action {
* @param $arguments
*/
public function runCommand(array $arguments) {
if ($arguments[1] === '_completion') {
if (!isset($arguments[1]) || $arguments[1] === '_completion') {
// Don't log autocompletion
return;
}

View File

@ -36,8 +36,8 @@ OC.L10N.register(
"You deleted todo {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}",
"{actor} updated todo {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}",
"You updated todo {todo} in list {calendar}" : "Променихте задача {todo} в списък {calendar}",
"{actor} solved todo {todo} in list {calendar}" : "{actor} реши задача {todo} в списък {calendar}",
"You solved todo {todo} in list {calendar}" : "Решихте задача {todo} в списък {calendar}",
"{actor} solved todo {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}",
"You solved todo {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}",
"{actor} reopened todo {todo} in list {calendar}" : "{actor} възобнови задача {todo} в списък {calendar}",
"You reopened todo {todo} in list {calendar}" : "Възобновихте задача {todo} в списък {calendar}",
"A <strong>calendar</strong> was modified" : "Промяна на <strong>календар</strong>",

View File

@ -34,8 +34,8 @@
"You deleted todo {todo} from list {calendar}" : "Изтрихте задача {todo} от списък {calendar}",
"{actor} updated todo {todo} in list {calendar}" : "{actor} актуализира задача {todo} в списък {calendar}",
"You updated todo {todo} in list {calendar}" : "Променихте задача {todo} в списък {calendar}",
"{actor} solved todo {todo} in list {calendar}" : "{actor} реши задача {todo} в списък {calendar}",
"You solved todo {todo} in list {calendar}" : "Решихте задача {todo} в списък {calendar}",
"{actor} solved todo {todo} in list {calendar}" : "{actor} разреши задача {todo} в списък {calendar}",
"You solved todo {todo} in list {calendar}" : "Разрешихте задача {todo} в списък {calendar}",
"{actor} reopened todo {todo} in list {calendar}" : "{actor} възобнови задача {todo} в списък {calendar}",
"You reopened todo {todo} in list {calendar}" : "Възобновихте задача {todo} в списък {calendar}",
"A <strong>calendar</strong> was modified" : "Промяна на <strong>календар</strong>",

View File

@ -78,7 +78,7 @@ class MaintenancePlugin extends ServerPlugin {
* @return bool
*/
public function checkMaintenanceMode() {
if ($this->config->getSystemValue('maintenance', false)) {
if ($this->config->getSystemValueBool('maintenance')) {
throw new ServiceUnavailable('System in maintenance mode.');
}
if (Util::needUpgrade()) {

View File

@ -53,7 +53,8 @@ class MaintenancePluginTest extends TestCase {
public function testMaintenanceMode() {
$this->config
->expects($this->exactly(1))
->method('getSystemValue')
->method('getSystemValueBool')
->with('maintenance')
->will($this->returnValue(true));
$this->maintenancePlugin->checkMaintenanceMode();

View File

@ -1,29 +1,66 @@
OC.L10N.register(
"encryption",
{
"Missing recovery key password" : "Mankas pasvorto de la restaŭroŝlosilo",
"Please repeat the recovery key password" : "Bv. ripeti la pasvorton de restaŭroŝlosilo",
"Repeated recovery key password does not match the provided recovery key password" : "La du pasvortoj pri la restaŭroŝlosilo ne kongruas",
"Recovery key successfully enabled" : "Restaŭroŝlosilo sukcese ebligita",
"Could not enable recovery key. Please check your recovery key password!" : "Restaŭroŝlosilo ne povis esti ŝaltita. Bv. kontroli vian pasvorton de restaŭroŝlosilo!",
"Recovery key successfully disabled" : "Restaŭroŝlosilo sukcese malŝaltita",
"Could not disable recovery key. Please check your recovery key password!" : "Restaŭroŝlosilo ne povis esti malŝaltita. Bv. kontroli vian pasvorton de restaŭroŝlosilo!",
"Missing parameters" : "Mankas parametroj",
"Please provide the old recovery password" : "Bv. doni la malnovan pasvorton de restaŭroŝlosilo",
"Please provide a new recovery password" : "Bv. doni la novan pasvorton de restaŭroŝlosilo",
"Please repeat the new recovery password" : "Bv. ripeti la novan pasvorton de restaŭroŝlosilo",
"Password successfully changed." : "La pasvorto sukcese ŝanĝiĝis.",
"Could not change the password. Maybe the old password was not correct." : "Ne eblis ŝanĝi la pasvorton. Eble la malnova pasvorto malĝustis.",
"Recovery Key disabled" : "Restaŭroŝlosilo malkapabliĝis",
"Recovery Key enabled" : "Restaŭroŝlosilo kapabliĝis",
"Private key password successfully updated." : "La pasvorto de la malpublika ŝlosilo sukcese ĝisdatiĝis.",
"Encryption App is enabled and ready" : "Aplikaĵo Ĉifrado kapabligitas kaj pretas",
"Recovery Key disabled" : "Restaŭroŝlosilo malŝaltita",
"Recovery Key enabled" : "Restaŭroŝlosilo ŝaltita",
"Could not enable the recovery key, please try again or contact your administrator" : "Restaŭroŝlosilo ne povis esti ŝaltita. Bv. re-provi aŭ kontakti vian administranton.",
"Could not update the private key password." : "Ne eblis ĝisdatigi la pasvorton de restaŭroŝlosilo.",
"The old password was not correct, please try again." : "La malnova pasvorto malĝustas. Provu denove.",
"The current log-in password was not correct, please try again." : "La aktuala ensalutpasvorto ne ĝustas. Bv. provi denove.",
"Private key password successfully updated." : "La pasvorto de la privata ŝlosilo sukcese ĝisdatiĝis.",
"Invalid private key for encryption app. Please update your private key password in your personal settings to recover access to your encrypted files." : "Nevalida privata ŝlosilo por la ĉifra aplikaĵo. Bv. ĝisdatigi la pasvorton de via privata ŝlosilo en viaj personaj agordoj por povi realiri al viaj ĉifritajn dosierojn.",
"Encryption App is enabled, but your keys are not initialized. Please log-out and log-in again." : "Ĉifra aplikaĵo estas ŝaltita, sed viaj ŝlosiloj ne uziĝas. Bv. elsaluti kaj re-ensaluti.",
"Please enable server side encryption in the admin settings in order to use the encryption module." : "Bv. ŝalti la ĉeservilan ĉifradon en la administraj agordoj por uzi la ĉifran modulon.",
"Encryption app is enabled and ready" : "La ĉifra aplikaĵo estas ŝaltita kaj preta",
"Bad Signature" : "Malbona subskribo",
"Missing Signature" : "Mankanta subskribo",
"one-time password for server-side-encryption" : "unuuza pasvorto por ĉeservila ĉifrado",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Ne eblas malĉifri tiun ĉi dosieron, probable kunhavigitan. Bv. demandi al posedanto re-kunhavigi la dosieron kun vi.",
"Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Ne eblas legi tiun ĉi dosieron, probable kunhavigitan. Bv. demandi al posedanto re-kunhavigi la dosieron kun vi.",
"Default encryption module" : "Defaŭlta ĉifra modulo",
"Default encryption module for server-side encryption" : "Defaŭlta ĉifra modulo por ĉeservila ĉifrado",
"In order to use this encryption module you need to enable server-side\n\t\tencryption in the admin settings. Once enabled this module will encrypt\n\t\tall your files transparently. The encryption is based on AES 256 keys.\n\t\tThe module won't touch existing files, only new files will be encrypted\n\t\tafter server-side encryption was enabled. It is also not possible to\n\t\tdisable the encryption again and switch back to a unencrypted system.\n\t\tPlease read the documentation to know all implications before you decide\n\t\tto enable server-side encryption." : "Por uzi tiun ĉifran modulon, vi bezonas ŝalti ĉeservilan ĉifradon en la administraj agordoj. Tiu modulo ĉifros ĉiujn viajn dosierojn netrudiĝeme. La ĉifrado baziĝas sur AES-ŝlosiloj de 256 bitoj.\nLa modulo ne ĉifros ekzistantajn dosierojn, nur la venontajn, post kiam la ĉeservila ĉifrado estis ŝaltita. Ankaŭ ne eblas malŝalti la ĉifradon kaj reiri al neĉifrita sistemo.\nBv. legi la dokumentaron por scii ĉiujn konsekvencojn, antaŭ ol decidi, ĉu vi uzos ĉeservilan ĉifradon.",
"Hey there,\n\nthe admin enabled server-side-encryption. Your files were encrypted using the password '%s'.\n\nPlease login to the web interface, go to the section 'basic encryption module' of your personal settings and update your encryption password by entering this password into the 'old log-in password' field and your current login-password.\n\n" : "Saluton,\n\nLa administranto ebligis ĉeservilan ĉifradon. Viaj dosieroj ĉifriĝis per la pasvorto „%s“.\n\nBonvolu ensaluti al la TTT-fasado, iri en viaj personaj agordoj al la parto „Bazĉifrada modulo“ por ĝisdatigi vian ĉifran pasvorton: en la kampo „Malnova ensaluta pasvorto“, skribu la ĉi-supran pasvorton kaj en la alia kampo vian nunan pasvorton.\n\n",
"The share will expire on %s." : "La kunhavo senvalidiĝos je %s.",
"Enable recovery key" : "Kapabligi restaŭroŝlosilon",
"Disable recovery key" : "Malkapabligi restaŭroŝlosilon",
"Cheers!" : "Ĝis!",
"Hey there,<br><br>the admin enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>Please login to the web interface, go to the section \"basic encryption module\" of your personal settings and update your encryption password by entering this password into the \"old log-in password\" field and your current login-password.<br><br>" : "Saluton,<br><br>La administranto ebligis ĉeservilan ĉifradon. Viaj dosieroj ĉifriĝis per la pasvorto <strong>%s</strong>.<br><br>Bonvolu ensaluti al la TTT-fasado, iri en viaj personaj agordoj al la parto „Bazĉifrada modulo“ por ĝisdatigi vian ĉifran pasvorton: en la kampo „Malnova ensaluta pasvorto“, skribu la ĉi-supran pasvorton kaj en la alia kampo vian nunan pasvorton.<br><br>",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Ĉifra aplikaĵo estas ŝaltita, sed viaj ŝlosiloj ne uziĝas. Bv. elsaluti kaj re-ensaluti.",
"Encrypt the home storage" : "Ĉifri la ĉefkonservejon",
"Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Ebligi tiun opcion ĉifras ĉiujn dosierojn de la ĉefkonservejo, alie nur dosieroj en ekstera konservejo ĉifriĝos.",
"Enable recovery key" : "Ŝalti restaŭroŝlosilon",
"Disable recovery key" : "Malŝalti restaŭroŝlosilon",
"The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "La restaŭroŝlosilo estas kroma ĉifroŝlosilo, kiu uziĝas por ĉifri dosierojn. Ĝi ebligas restaŭron el dosieroj de uzanto, se la uzanto forgesas sian pasvorton.",
"Recovery key password" : "Pasvorto de restaŭroŝlosilo",
"Repeat recovery key password" : "Ripetu la pasvorton de restaŭroŝlosilo",
"Change recovery key password:" : "Ŝanĝi la pasvorton de la restaŭroŝlosilo:",
"Old recovery key password" : "Malnova pasvorto de restaŭroŝlosilo",
"New recovery key password" : "Nova pasvorto de restaŭroŝlosilo",
"Repeat new recovery key password" : "Ripetu la novan pasvorton de restaŭroŝlosilo",
"Change Password" : "Ŝarĝi pasvorton",
"basic encryption module" : "Baza ĉifrada modulo de",
"Change Password" : "Ŝanĝi pasvorton",
"Basic encryption module" : "Bazĉifrada modulo",
"Your private key password no longer matches your log-in password." : "La pasvorto de via privata ŝlosilo ne plu kongruas kun via ensaluta pasvorto.",
"Set your old private key password to your current log-in password:" : "Agordi la pasvorton de via antaŭa privata ŝlosilo al via nuna ensaluta pasvorto:",
" If you don't remember your old password you can ask your administrator to recover your files." : "Se vi ne memoras vian antaŭan pasvorton, vi povas peti al via administranto restaŭri viajn dosierojn.",
"Old log-in password" : "Malnova ensaluta pasvorto",
"Current log-in password" : "Nuna ensaluta pasvorto",
"Update Private Key Password" : "Ĝisdatigi la pasvorton de la malpublika ŝlosilo",
"Enable password recovery:" : "Kapabligi restaŭron de pasvorto:",
"Enabled" : "Kapabligita",
"Disabled" : "Malkapabligita"
"Enable password recovery:" : "Ŝalti restaŭron de pasvorto:",
"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Ŝalti tiun opcion ebligas al vi rehavi aliron al viaj ĉifritaj dosierojn okaze de pasvorta perdo.",
"Enabled" : "Ŝaltita",
"Disabled" : "Malŝaltita",
"You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run 'occ encryption:migrate' or contact your administrator" : "Vi devas transigi viajn ĉifroŝlosilojn el antaŭa versio (ownCloud ⩽ 8.0) al nova. Bv. ruli komandlinie „occ encryption:migrate“ aŭ kontakti vian administranton."
},
"nplurals=2; plural=(n != 1);");

View File

@ -1,27 +1,64 @@
{ "translations": {
"Missing recovery key password" : "Mankas pasvorto de la restaŭroŝlosilo",
"Please repeat the recovery key password" : "Bv. ripeti la pasvorton de restaŭroŝlosilo",
"Repeated recovery key password does not match the provided recovery key password" : "La du pasvortoj pri la restaŭroŝlosilo ne kongruas",
"Recovery key successfully enabled" : "Restaŭroŝlosilo sukcese ebligita",
"Could not enable recovery key. Please check your recovery key password!" : "Restaŭroŝlosilo ne povis esti ŝaltita. Bv. kontroli vian pasvorton de restaŭroŝlosilo!",
"Recovery key successfully disabled" : "Restaŭroŝlosilo sukcese malŝaltita",
"Could not disable recovery key. Please check your recovery key password!" : "Restaŭroŝlosilo ne povis esti malŝaltita. Bv. kontroli vian pasvorton de restaŭroŝlosilo!",
"Missing parameters" : "Mankas parametroj",
"Please provide the old recovery password" : "Bv. doni la malnovan pasvorton de restaŭroŝlosilo",
"Please provide a new recovery password" : "Bv. doni la novan pasvorton de restaŭroŝlosilo",
"Please repeat the new recovery password" : "Bv. ripeti la novan pasvorton de restaŭroŝlosilo",
"Password successfully changed." : "La pasvorto sukcese ŝanĝiĝis.",
"Could not change the password. Maybe the old password was not correct." : "Ne eblis ŝanĝi la pasvorton. Eble la malnova pasvorto malĝustis.",
"Recovery Key disabled" : "Restaŭroŝlosilo malkapabliĝis",
"Recovery Key enabled" : "Restaŭroŝlosilo kapabliĝis",
"Private key password successfully updated." : "La pasvorto de la malpublika ŝlosilo sukcese ĝisdatiĝis.",
"Encryption App is enabled and ready" : "Aplikaĵo Ĉifrado kapabligitas kaj pretas",
"Recovery Key disabled" : "Restaŭroŝlosilo malŝaltita",
"Recovery Key enabled" : "Restaŭroŝlosilo ŝaltita",
"Could not enable the recovery key, please try again or contact your administrator" : "Restaŭroŝlosilo ne povis esti ŝaltita. Bv. re-provi aŭ kontakti vian administranton.",
"Could not update the private key password." : "Ne eblis ĝisdatigi la pasvorton de restaŭroŝlosilo.",
"The old password was not correct, please try again." : "La malnova pasvorto malĝustas. Provu denove.",
"The current log-in password was not correct, please try again." : "La aktuala ensalutpasvorto ne ĝustas. Bv. provi denove.",
"Private key password successfully updated." : "La pasvorto de la privata ŝlosilo sukcese ĝisdatiĝis.",
"Invalid private key for encryption app. Please update your private key password in your personal settings to recover access to your encrypted files." : "Nevalida privata ŝlosilo por la ĉifra aplikaĵo. Bv. ĝisdatigi la pasvorton de via privata ŝlosilo en viaj personaj agordoj por povi realiri al viaj ĉifritajn dosierojn.",
"Encryption App is enabled, but your keys are not initialized. Please log-out and log-in again." : "Ĉifra aplikaĵo estas ŝaltita, sed viaj ŝlosiloj ne uziĝas. Bv. elsaluti kaj re-ensaluti.",
"Please enable server side encryption in the admin settings in order to use the encryption module." : "Bv. ŝalti la ĉeservilan ĉifradon en la administraj agordoj por uzi la ĉifran modulon.",
"Encryption app is enabled and ready" : "La ĉifra aplikaĵo estas ŝaltita kaj preta",
"Bad Signature" : "Malbona subskribo",
"Missing Signature" : "Mankanta subskribo",
"one-time password for server-side-encryption" : "unuuza pasvorto por ĉeservila ĉifrado",
"Can not decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Ne eblas malĉifri tiun ĉi dosieron, probable kunhavigitan. Bv. demandi al posedanto re-kunhavigi la dosieron kun vi.",
"Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Ne eblas legi tiun ĉi dosieron, probable kunhavigitan. Bv. demandi al posedanto re-kunhavigi la dosieron kun vi.",
"Default encryption module" : "Defaŭlta ĉifra modulo",
"Default encryption module for server-side encryption" : "Defaŭlta ĉifra modulo por ĉeservila ĉifrado",
"In order to use this encryption module you need to enable server-side\n\t\tencryption in the admin settings. Once enabled this module will encrypt\n\t\tall your files transparently. The encryption is based on AES 256 keys.\n\t\tThe module won't touch existing files, only new files will be encrypted\n\t\tafter server-side encryption was enabled. It is also not possible to\n\t\tdisable the encryption again and switch back to a unencrypted system.\n\t\tPlease read the documentation to know all implications before you decide\n\t\tto enable server-side encryption." : "Por uzi tiun ĉifran modulon, vi bezonas ŝalti ĉeservilan ĉifradon en la administraj agordoj. Tiu modulo ĉifros ĉiujn viajn dosierojn netrudiĝeme. La ĉifrado baziĝas sur AES-ŝlosiloj de 256 bitoj.\nLa modulo ne ĉifros ekzistantajn dosierojn, nur la venontajn, post kiam la ĉeservila ĉifrado estis ŝaltita. Ankaŭ ne eblas malŝalti la ĉifradon kaj reiri al neĉifrita sistemo.\nBv. legi la dokumentaron por scii ĉiujn konsekvencojn, antaŭ ol decidi, ĉu vi uzos ĉeservilan ĉifradon.",
"Hey there,\n\nthe admin enabled server-side-encryption. Your files were encrypted using the password '%s'.\n\nPlease login to the web interface, go to the section 'basic encryption module' of your personal settings and update your encryption password by entering this password into the 'old log-in password' field and your current login-password.\n\n" : "Saluton,\n\nLa administranto ebligis ĉeservilan ĉifradon. Viaj dosieroj ĉifriĝis per la pasvorto „%s“.\n\nBonvolu ensaluti al la TTT-fasado, iri en viaj personaj agordoj al la parto „Bazĉifrada modulo“ por ĝisdatigi vian ĉifran pasvorton: en la kampo „Malnova ensaluta pasvorto“, skribu la ĉi-supran pasvorton kaj en la alia kampo vian nunan pasvorton.\n\n",
"The share will expire on %s." : "La kunhavo senvalidiĝos je %s.",
"Enable recovery key" : "Kapabligi restaŭroŝlosilon",
"Disable recovery key" : "Malkapabligi restaŭroŝlosilon",
"Cheers!" : "Ĝis!",
"Hey there,<br><br>the admin enabled server-side-encryption. Your files were encrypted using the password <strong>%s</strong>.<br><br>Please login to the web interface, go to the section \"basic encryption module\" of your personal settings and update your encryption password by entering this password into the \"old log-in password\" field and your current login-password.<br><br>" : "Saluton,<br><br>La administranto ebligis ĉeservilan ĉifradon. Viaj dosieroj ĉifriĝis per la pasvorto <strong>%s</strong>.<br><br>Bonvolu ensaluti al la TTT-fasado, iri en viaj personaj agordoj al la parto „Bazĉifrada modulo“ por ĝisdatigi vian ĉifran pasvorton: en la kampo „Malnova ensaluta pasvorto“, skribu la ĉi-supran pasvorton kaj en la alia kampo vian nunan pasvorton.<br><br>",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Ĉifra aplikaĵo estas ŝaltita, sed viaj ŝlosiloj ne uziĝas. Bv. elsaluti kaj re-ensaluti.",
"Encrypt the home storage" : "Ĉifri la ĉefkonservejon",
"Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted" : "Ebligi tiun opcion ĉifras ĉiujn dosierojn de la ĉefkonservejo, alie nur dosieroj en ekstera konservejo ĉifriĝos.",
"Enable recovery key" : "Ŝalti restaŭroŝlosilon",
"Disable recovery key" : "Malŝalti restaŭroŝlosilon",
"The recovery key is an extra encryption key that is used to encrypt files. It allows recovery of a user's files if the user forgets his or her password." : "La restaŭroŝlosilo estas kroma ĉifroŝlosilo, kiu uziĝas por ĉifri dosierojn. Ĝi ebligas restaŭron el dosieroj de uzanto, se la uzanto forgesas sian pasvorton.",
"Recovery key password" : "Pasvorto de restaŭroŝlosilo",
"Repeat recovery key password" : "Ripetu la pasvorton de restaŭroŝlosilo",
"Change recovery key password:" : "Ŝanĝi la pasvorton de la restaŭroŝlosilo:",
"Old recovery key password" : "Malnova pasvorto de restaŭroŝlosilo",
"New recovery key password" : "Nova pasvorto de restaŭroŝlosilo",
"Repeat new recovery key password" : "Ripetu la novan pasvorton de restaŭroŝlosilo",
"Change Password" : "Ŝarĝi pasvorton",
"basic encryption module" : "Baza ĉifrada modulo de",
"Change Password" : "Ŝanĝi pasvorton",
"Basic encryption module" : "Bazĉifrada modulo",
"Your private key password no longer matches your log-in password." : "La pasvorto de via privata ŝlosilo ne plu kongruas kun via ensaluta pasvorto.",
"Set your old private key password to your current log-in password:" : "Agordi la pasvorton de via antaŭa privata ŝlosilo al via nuna ensaluta pasvorto:",
" If you don't remember your old password you can ask your administrator to recover your files." : "Se vi ne memoras vian antaŭan pasvorton, vi povas peti al via administranto restaŭri viajn dosierojn.",
"Old log-in password" : "Malnova ensaluta pasvorto",
"Current log-in password" : "Nuna ensaluta pasvorto",
"Update Private Key Password" : "Ĝisdatigi la pasvorton de la malpublika ŝlosilo",
"Enable password recovery:" : "Kapabligi restaŭron de pasvorto:",
"Enabled" : "Kapabligita",
"Disabled" : "Malkapabligita"
"Enable password recovery:" : "Ŝalti restaŭron de pasvorto:",
"Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" : "Ŝalti tiun opcion ebligas al vi rehavi aliron al viaj ĉifritaj dosierojn okaze de pasvorta perdo.",
"Enabled" : "Ŝaltita",
"Disabled" : "Malŝaltita",
"You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run 'occ encryption:migrate' or contact your administrator" : "Vi devas transigi viajn ĉifroŝlosilojn el antaŭa versio (ownCloud ⩽ 8.0) al nova. Bv. ruli komandlinie „occ encryption:migrate“ aŭ kontakti vian administranton."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

View File

@ -75,7 +75,7 @@ class Application extends \OCP\AppFramework\App {
* register hooks
*/
public function registerHooks() {
if (!$this->config->getSystemValue('maintenance', false)) {
if (!$this->config->getSystemValueBool('maintenance')) {
$container = $this->getContainer();
$server = $container->getServer();

View File

@ -1,7 +1,7 @@
OC.L10N.register(
"federatedfilesharing",
{
"Federated sharing" : "Udostępnianie Stowarzyszone",
"Federated sharing" : "Udostępnianie Federacyjne",
"Do you want to add the remote share {name} from {owner}@{remote}?" : "Chcesz się dzielić zdalnie {name} z {owner}@{remote}?",
"Remote share" : "Zdalny zasób",
"Remote share password" : "Hasło do zdalnego zasobu",
@ -12,15 +12,15 @@ OC.L10N.register(
"Not supported!" : "Brak wsparcia!",
"Press ⌘-C to copy." : "Wciśnij ⌘-C by skopiować.",
"Press Ctrl-C to copy." : "Wciśnij Ctrl-C by skopiować.",
"Invalid Federated Cloud ID" : "Nieprawidłowy identyfikator Stowarzyszonej Chmury",
"Invalid Federated Cloud ID" : "Nieprawidłowy identyfikator Federacyjnej Chmury",
"Server to server sharing is not enabled on this server" : "Serwer do udostępniania serwera nie jest włączony na tym serwerze",
"Couldn't establish a federated share." : "Nie udało się ustalić Stowarzyszonego udostępnienia.",
"Couldn't establish a federated share, maybe the password was wrong." : "Nie udało się ustalić Stowarzyszonego udostępnienia, może być błędne hasło.",
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Wysłano żądanie Udostępniania Stowarzyszonego, otrzymasz zaproszenie. Sprawdzaj swoje powiadomienia.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Nie można ustanowić stowarzyszonego udziału, wygląda na to, że serwer wybrany do stowarzyszenia jest zbyt stary (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Wysyłanie stowarzyszonych udziałów grupowych z tego serwera jest zabronione.",
"Couldn't establish a federated share." : "Nie udało się ustalić Federacyjnego udostępnienia.",
"Couldn't establish a federated share, maybe the password was wrong." : "Nie udało się ustalić Federacyjnego udostępnienia, może być błędne hasło.",
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Wysłano żądanie Udostępniania Federacyjnego, otrzymasz zaproszenie. Sprawdzaj swoje powiadomienia.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Nie można ustanowić federacyjnego udziału, wygląda na to, że serwer wybrany do stowarzyszenia jest zbyt stary (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Wysyłanie federacyjnych udziałów grupowych z tego serwera jest zabronione.",
"Sharing %1$s failed, because this item is already shared with %2$s" : "Udostępnianie %1$snie powiodło się, ponieważ ten element jest już udostępniony jako %2$s",
"Not allowed to create a federated share with the same user" : "Nie można tworzyć stowarzyszonego udziału z tym samym użytkownikiem",
"Not allowed to create a federated share with the same user" : "Nie można tworzyć federacyjnego udziału z tym samym użytkownikiem",
"File is already shared with %s" : "Plik jest już współdzielony z %s",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "Udostępnianie %1$s nie powiodło się, nie można odnaleźć %2$s, być może serwer jest nieosiągalny lub używa certyfikatu z podpisem własnym.",
"Could not find share" : "Nie można znaleźć powiązania",
@ -30,12 +30,12 @@ OC.L10N.register(
"You received {share} as a remote share from {user}" : "Otrzymałeś {share} w zdalnym udziale {user}",
"Accept" : "Akceptuj",
"Decline" : "Utrata",
"Share with me through my #Nextcloud Federated Cloud ID, see %s" : "Podziel się ze mną przez mój ID #Nextcloud Stowarzyszonej Chmury, zobacz %s",
"Share with me through my #Nextcloud Federated Cloud ID" : "Podziel się ze mną przez mój ID #Nextcloud Stowarzyszonej Chmury",
"Share with me through my #Nextcloud Federated Cloud ID, see %s" : "Podziel się ze mną przez mój ID #Nextcloud Federacyjnej Chmury, zobacz %s",
"Share with me through my #Nextcloud Federated Cloud ID" : "Podziel się ze mną przez mój ID #Nextcloud Federacyjnej Chmury",
"Sharing" : "Udostępnianie",
"Federated file sharing" : "Stowarzyszone udziały grupowe",
"Provide federated file sharing across servers" : "Zezwól na stowarzyszone udostępnianie plików na serwerach",
"Federated Cloud Sharing" : "Dzielenie się ze Stowarzyszoną Chmurą",
"Federated file sharing" : "Federacyjne udostępnianie plików",
"Provide federated file sharing across servers" : "Zezwól na federacyjne udostępnianie plików na serwerach",
"Federated Cloud Sharing" : "Dzielenie się ze Federacyjną Chmurą",
"Open documentation" : "Otwórz dokumentację",
"Adjust how people can share between servers." : "Dostosuj ustawienia współdzielenia między serwerami.",
"Allow users on this server to send shares to other servers" : "Zezwalaj użytkownikom na tym serwerze wysłać udostępnienia do innych serwerów",
@ -44,19 +44,19 @@ OC.L10N.register(
"Allow users on this server to receive group shares from other servers" : "Pozwól użytkownikom na tym serwerze na odbieranie udziałów grupy z innych serwerów",
"Search global and public address book for users" : "Szukaj użytkowników w globalnej i publicznej książce adresowej",
"Allow users to publish their data to a global and public address book" : "Pozwól użytkownikom na publikację ich danych do globalnej i publicznej książki adresowej",
"Federated Cloud" : "Stowarzyszona Chmura",
"You can share with anyone who uses Nextcloud, ownCloud or Pydio! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Możesz współdzielić z każdym kto używa Nextclouda, ownClouda lub Pydio. Wystarczy, że wpiszesz ich ID chmury stowarzyszonej w pole współdzielenia. Wygląda jak osoba@przyklad.chmury.com",
"Your Federated Cloud ID:" : "Twoje ID Stowarzyszonej Chmury:",
"Federated Cloud" : "Federacyjna Chmura",
"You can share with anyone who uses Nextcloud, ownCloud or Pydio! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Możesz współdzielić z każdym, kto używa Nextclouda, ownClouda lub Pydio. Wystarczy, że wpiszesz ich ID Federacyjnej Chmury w pole współdzielenia. Wygląda jak osoba@chmura.przykład.com",
"Your Federated Cloud ID:" : "Twoje ID Federacyjnej Chmury:",
"Share it so your friends can share files with you:" : "Współdziel to, aby Twoi przyjaciele mogli współdzielić pliki z Tobą:",
"Add to your website" : "Dodaj do swojej strony",
"Share with me via Nextcloud" : "Podziel się ze mną poprzez Nextcloud",
"HTML Code:" : "Kod HTML:",
"The mountpoint name contains invalid characters." : "Nazwa zamontowanego zasobu zawiera niedozwolone znaki.",
"Not allowed to create a federated share with the owner." : "Nie można tworzyć stowarzyszonego udziału ze sobą.",
"Not allowed to create a federated share with the owner." : "Nie można tworzyć federacyjnego udziału ze sobą.",
"Invalid or untrusted SSL certificate" : "Niewłaściwy lub niezaufany certyfikat SSL",
"Could not authenticate to remote share, password might be wrong" : "Nie udało się uwierzytelnić udziału zdalnego, może być błędne hasło",
"Storage not valid" : "Magazyn nie jest prawidłowy",
"Federated share added" : "Udostępnianie Stowarzyszone zostało dodane",
"Federated share added" : "Udostępnianie Federacyjne zostało dodane",
"Couldn't add remote share" : "Nie można dodać zdalnego zasobu",
"Sharing %s failed, because this item is already shared with %s" : "Współdzielenie %s nie powiodło się, ponieważ element jest już współdzielony z %s",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate." : "Dzielenie %s nie powiodło się. Nie można było znaleźć %s, być może serwer jest obecnie nieosiągalny lub używa certyfikatu z podpisem własnym."

View File

@ -1,5 +1,5 @@
{ "translations": {
"Federated sharing" : "Udostępnianie Stowarzyszone",
"Federated sharing" : "Udostępnianie Federacyjne",
"Do you want to add the remote share {name} from {owner}@{remote}?" : "Chcesz się dzielić zdalnie {name} z {owner}@{remote}?",
"Remote share" : "Zdalny zasób",
"Remote share password" : "Hasło do zdalnego zasobu",
@ -10,15 +10,15 @@
"Not supported!" : "Brak wsparcia!",
"Press ⌘-C to copy." : "Wciśnij ⌘-C by skopiować.",
"Press Ctrl-C to copy." : "Wciśnij Ctrl-C by skopiować.",
"Invalid Federated Cloud ID" : "Nieprawidłowy identyfikator Stowarzyszonej Chmury",
"Invalid Federated Cloud ID" : "Nieprawidłowy identyfikator Federacyjnej Chmury",
"Server to server sharing is not enabled on this server" : "Serwer do udostępniania serwera nie jest włączony na tym serwerze",
"Couldn't establish a federated share." : "Nie udało się ustalić Stowarzyszonego udostępnienia.",
"Couldn't establish a federated share, maybe the password was wrong." : "Nie udało się ustalić Stowarzyszonego udostępnienia, może być błędne hasło.",
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Wysłano żądanie Udostępniania Stowarzyszonego, otrzymasz zaproszenie. Sprawdzaj swoje powiadomienia.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Nie można ustanowić stowarzyszonego udziału, wygląda na to, że serwer wybrany do stowarzyszenia jest zbyt stary (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Wysyłanie stowarzyszonych udziałów grupowych z tego serwera jest zabronione.",
"Couldn't establish a federated share." : "Nie udało się ustalić Federacyjnego udostępnienia.",
"Couldn't establish a federated share, maybe the password was wrong." : "Nie udało się ustalić Federacyjnego udostępnienia, może być błędne hasło.",
"Federated Share request sent, you will receive an invitation. Check your notifications." : "Wysłano żądanie Udostępniania Federacyjnego, otrzymasz zaproszenie. Sprawdzaj swoje powiadomienia.",
"Couldn't establish a federated share, it looks like the server to federate with is too old (Nextcloud <= 9)." : "Nie można ustanowić federacyjnego udziału, wygląda na to, że serwer wybrany do stowarzyszenia jest zbyt stary (Nextcloud <= 9).",
"It is not allowed to send federated group shares from this server." : "Wysyłanie federacyjnych udziałów grupowych z tego serwera jest zabronione.",
"Sharing %1$s failed, because this item is already shared with %2$s" : "Udostępnianie %1$snie powiodło się, ponieważ ten element jest już udostępniony jako %2$s",
"Not allowed to create a federated share with the same user" : "Nie można tworzyć stowarzyszonego udziału z tym samym użytkownikiem",
"Not allowed to create a federated share with the same user" : "Nie można tworzyć federacyjnego udziału z tym samym użytkownikiem",
"File is already shared with %s" : "Plik jest już współdzielony z %s",
"Sharing %1$s failed, could not find %2$s, maybe the server is currently unreachable or uses a self-signed certificate." : "Udostępnianie %1$s nie powiodło się, nie można odnaleźć %2$s, być może serwer jest nieosiągalny lub używa certyfikatu z podpisem własnym.",
"Could not find share" : "Nie można znaleźć powiązania",
@ -28,12 +28,12 @@
"You received {share} as a remote share from {user}" : "Otrzymałeś {share} w zdalnym udziale {user}",
"Accept" : "Akceptuj",
"Decline" : "Utrata",
"Share with me through my #Nextcloud Federated Cloud ID, see %s" : "Podziel się ze mną przez mój ID #Nextcloud Stowarzyszonej Chmury, zobacz %s",
"Share with me through my #Nextcloud Federated Cloud ID" : "Podziel się ze mną przez mój ID #Nextcloud Stowarzyszonej Chmury",
"Share with me through my #Nextcloud Federated Cloud ID, see %s" : "Podziel się ze mną przez mój ID #Nextcloud Federacyjnej Chmury, zobacz %s",
"Share with me through my #Nextcloud Federated Cloud ID" : "Podziel się ze mną przez mój ID #Nextcloud Federacyjnej Chmury",
"Sharing" : "Udostępnianie",
"Federated file sharing" : "Stowarzyszone udziały grupowe",
"Provide federated file sharing across servers" : "Zezwól na stowarzyszone udostępnianie plików na serwerach",
"Federated Cloud Sharing" : "Dzielenie się ze Stowarzyszoną Chmurą",
"Federated file sharing" : "Federacyjne udostępnianie plików",
"Provide federated file sharing across servers" : "Zezwól na federacyjne udostępnianie plików na serwerach",
"Federated Cloud Sharing" : "Dzielenie się ze Federacyjną Chmurą",
"Open documentation" : "Otwórz dokumentację",
"Adjust how people can share between servers." : "Dostosuj ustawienia współdzielenia między serwerami.",
"Allow users on this server to send shares to other servers" : "Zezwalaj użytkownikom na tym serwerze wysłać udostępnienia do innych serwerów",
@ -42,19 +42,19 @@
"Allow users on this server to receive group shares from other servers" : "Pozwól użytkownikom na tym serwerze na odbieranie udziałów grupy z innych serwerów",
"Search global and public address book for users" : "Szukaj użytkowników w globalnej i publicznej książce adresowej",
"Allow users to publish their data to a global and public address book" : "Pozwól użytkownikom na publikację ich danych do globalnej i publicznej książki adresowej",
"Federated Cloud" : "Stowarzyszona Chmura",
"You can share with anyone who uses Nextcloud, ownCloud or Pydio! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Możesz współdzielić z każdym kto używa Nextclouda, ownClouda lub Pydio. Wystarczy, że wpiszesz ich ID chmury stowarzyszonej w pole współdzielenia. Wygląda jak osoba@przyklad.chmury.com",
"Your Federated Cloud ID:" : "Twoje ID Stowarzyszonej Chmury:",
"Federated Cloud" : "Federacyjna Chmura",
"You can share with anyone who uses Nextcloud, ownCloud or Pydio! Just put their Federated Cloud ID in the share dialog. It looks like person@cloud.example.com" : "Możesz współdzielić z każdym, kto używa Nextclouda, ownClouda lub Pydio. Wystarczy, że wpiszesz ich ID Federacyjnej Chmury w pole współdzielenia. Wygląda jak osoba@chmura.przykład.com",
"Your Federated Cloud ID:" : "Twoje ID Federacyjnej Chmury:",
"Share it so your friends can share files with you:" : "Współdziel to, aby Twoi przyjaciele mogli współdzielić pliki z Tobą:",
"Add to your website" : "Dodaj do swojej strony",
"Share with me via Nextcloud" : "Podziel się ze mną poprzez Nextcloud",
"HTML Code:" : "Kod HTML:",
"The mountpoint name contains invalid characters." : "Nazwa zamontowanego zasobu zawiera niedozwolone znaki.",
"Not allowed to create a federated share with the owner." : "Nie można tworzyć stowarzyszonego udziału ze sobą.",
"Not allowed to create a federated share with the owner." : "Nie można tworzyć federacyjnego udziału ze sobą.",
"Invalid or untrusted SSL certificate" : "Niewłaściwy lub niezaufany certyfikat SSL",
"Could not authenticate to remote share, password might be wrong" : "Nie udało się uwierzytelnić udziału zdalnego, może być błędne hasło",
"Storage not valid" : "Magazyn nie jest prawidłowy",
"Federated share added" : "Udostępnianie Stowarzyszone zostało dodane",
"Federated share added" : "Udostępnianie Federacyjne zostało dodane",
"Couldn't add remote share" : "Nie można dodać zdalnego zasobu",
"Sharing %s failed, because this item is already shared with %s" : "Współdzielenie %s nie powiodło się, ponieważ element jest już współdzielony z %s",
"Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate." : "Dzielenie %s nie powiodło się. Nie można było znaleźć %s, być może serwer jest obecnie nieosiągalny lub używa certyfikatu z podpisem własnym."

View File

@ -3,13 +3,13 @@ OC.L10N.register(
{
"Added to the list of trusted servers" : "Dodano do listy zaufanych serwerów.",
"Server is already in the list of trusted servers." : "Serwer znajduje się już na liście zaufanych serwerów.",
"No server to federate with found" : "Nie znaleziono stowarzyszonego serwera",
"No server to federate with found" : "Nie znaleziono federacyjnego serwera",
"Could not add server" : "Nie można dodać serwera",
"Federation" : "Stowarzyszenia",
"Federation allows you to connect with other trusted servers to exchange the user directory." : "Stowarzyszenie umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu użytkownika.",
"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." : "Stowarzyszenie pozwala łączyć się z innymi zaufanymi użytkownikami i wymieniać się z nimi katalogami. Na przykład, może to być wykorzystane do autouzupełniania w dzieleniu się ze stowarzyszonym użytkownikiem.",
"Federation" : "Federacje",
"Federation allows you to connect with other trusted servers to exchange the user directory." : "Federacje umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu użytkownika.",
"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." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu użytkownika. Na przykład będzie to używane do automatycznego uzupełniania zewnętrznych użytkowników w celu udostępnienia federacyjnego.",
"Trusted servers" : "Zaufane serwery",
"Add server automatically once a federated share was created successfully" : "Dodaj serwer automatycznie po pomyślnym utworzeniu stowarzyszonego udziału.",
"Add server automatically once a federated share was created successfully" : "Dodaj serwer automatycznie po pomyślnym utworzeniu federacyjnego udziału.",
"+ Add trusted server" : "+ Dodaj zaufany serwer",
"Trusted server" : "Zaufany serwer",
"Add" : "Dodaj"

View File

@ -1,13 +1,13 @@
{ "translations": {
"Added to the list of trusted servers" : "Dodano do listy zaufanych serwerów.",
"Server is already in the list of trusted servers." : "Serwer znajduje się już na liście zaufanych serwerów.",
"No server to federate with found" : "Nie znaleziono stowarzyszonego serwera",
"No server to federate with found" : "Nie znaleziono federacyjnego serwera",
"Could not add server" : "Nie można dodać serwera",
"Federation" : "Stowarzyszenia",
"Federation allows you to connect with other trusted servers to exchange the user directory." : "Stowarzyszenie umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu użytkownika.",
"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." : "Stowarzyszenie pozwala łączyć się z innymi zaufanymi użytkownikami i wymieniać się z nimi katalogami. Na przykład, może to być wykorzystane do autouzupełniania w dzieleniu się ze stowarzyszonym użytkownikiem.",
"Federation" : "Federacje",
"Federation allows you to connect with other trusted servers to exchange the user directory." : "Federacje umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu użytkownika.",
"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." : "Federacja umożliwia łączenie się z innymi zaufanymi serwerami w celu wymiany katalogu użytkownika. Na przykład będzie to używane do automatycznego uzupełniania zewnętrznych użytkowników w celu udostępnienia federacyjnego.",
"Trusted servers" : "Zaufane serwery",
"Add server automatically once a federated share was created successfully" : "Dodaj serwer automatycznie po pomyślnym utworzeniu stowarzyszonego udziału.",
"Add server automatically once a federated share was created successfully" : "Dodaj serwer automatycznie po pomyślnym utworzeniu federacyjnego udziału.",
"+ Add trusted server" : "+ Dodaj zaufany serwer",
"Trusted server" : "Zaufany serwer",
"Add" : "Dodaj"

View File

@ -199,7 +199,7 @@ table.multiselect th .columntitle {
display: inline-block;
}
table th .columntitle.name {
padding-left: 5px;
padding-left: 0;
margin-left: 50px;
}

View File

@ -94,6 +94,11 @@ return [
'url' => '/api/v1/sharees',
'verb' => 'GET',
],
[
'name' => 'ShareesAPI#findRecommended',
'url' => '/api/v1/sharees_recommended',
'verb' => 'GET',
],
/*
* Remote Shares
*/

View File

@ -22,6 +22,7 @@ OC.L10N.register(
"Download" : "下载",
"Delete" : "删除",
"You can upload into this folder" : "您可以上传文件至此文件夹",
"Terms of service" : "服务条款",
"No compatible server found at {remote}" : " {remote} 未发现匹配的服务器",
"Invalid server URL" : "无效的服务器地址",
"Failed to add the public link to your Nextcloud" : "添加公开链接到您的 Nextcloud 失败",

View File

@ -20,6 +20,7 @@
"Download" : "下载",
"Delete" : "删除",
"You can upload into this folder" : "您可以上传文件至此文件夹",
"Terms of service" : "服务条款",
"No compatible server found at {remote}" : " {remote} 未发现匹配的服务器",
"Invalid server URL" : "无效的服务器地址",
"Failed to add the public link to your Nextcloud" : "添加公开链接到您的 Nextcloud 失败",

View File

@ -361,6 +361,7 @@ class ShareController extends AuthPublicShareController {
$folder->assign('isPublic', true);
$folder->assign('hideFileList', $hideFileList);
$folder->assign('publicUploadEnabled', 'no');
// default to list view
$folder->assign('showgridview', false);
$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
@ -372,6 +373,7 @@ class ShareController extends AuthPublicShareController {
$shareIsFolder = false;
}
// default to list view
$shareTmpl['showgridview'] = false;
$shareTmpl['hideFileList'] = $hideFileList;

View File

@ -29,17 +29,29 @@ declare(strict_types=1);
*/
namespace OCA\Files_Sharing\Controller;
use function array_filter;
use function array_slice;
use function array_values;
use Generator;
use OC\Collaboration\Collaborators\SearchResult;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCSController;
use OCP\Collaboration\Collaborators\ISearch;
use OCP\Collaboration\Collaborators\ISearchResult;
use OCP\Collaboration\Collaborators\SearchResultType;
use OCP\IRequest;
use OCP\IConfig;
use OCP\IURLGenerator;
use OCP\Share;
use OCP\Share\IManager;
use function usort;
class ShareesAPIController extends OCSController {
/** @var userId */
protected $userId;
/** @var IConfig */
protected $config;
@ -87,6 +99,7 @@ class ShareesAPIController extends OCSController {
private $collaboratorSearch;
/**
* @param string $UserId
* @param string $appName
* @param IRequest $request
* @param IConfig $config
@ -95,6 +108,7 @@ class ShareesAPIController extends OCSController {
* @param ISearch $collaboratorSearch
*/
public function __construct(
$UserId,
string $appName,
IRequest $request,
IConfig $config,
@ -103,7 +117,7 @@ class ShareesAPIController extends OCSController {
ISearch $collaboratorSearch
) {
parent::__construct($appName, $request);
$this->userId = $UserId;
$this->config = $config;
$this->urlGenerator = $urlGenerator;
$this->shareManager = $shareManager;
@ -212,6 +226,148 @@ class ShareesAPIController extends OCSController {
return $response;
}
/**
* @param string $user
* @param int $shareType
*
* @return Generator<array<string>>
*/
private function getAllShareesByType(string $user, int $shareType): Generator {
$offset = 0;
$pageSize = 50;
while (count($page = $this->shareManager->getSharesBy(
$user,
$shareType,
null,
false,
$pageSize,
$offset
))) {
foreach ($page as $share) {
yield [$share->getSharedWith(), $share->getSharedWithDisplayName() ?? $share->getSharedWith()];
}
$offset += $pageSize;
}
}
private function sortShareesByFrequency(array $sharees): array {
usort($sharees, function(array $s1, array $s2) {
return $s2['count'] - $s1['count'];
});
return $sharees;
}
private $searchResultTypeMap = [
Share::SHARE_TYPE_USER => 'users',
Share::SHARE_TYPE_GROUP => 'groups',
Share::SHARE_TYPE_REMOTE => 'remotes',
Share::SHARE_TYPE_REMOTE_GROUP => 'remote_groups',
Share::SHARE_TYPE_EMAIL => 'emails',
];
private function getAllSharees(string $user, array $shareTypes): ISearchResult {
$result = [];
foreach ($shareTypes as $shareType) {
$sharees = $this->getAllShareesByType($user, $shareType);
$shareTypeResults = [];
foreach ($sharees as list($sharee, $displayname)) {
if (!isset($this->searchResultTypeMap[$shareType])) {
continue;
}
if (!isset($shareTypeResults[$sharee])) {
$shareTypeResults[$sharee] = [
'count' => 1,
'label' => $displayname,
'value' => [
'shareType' => $shareType,
'shareWith' => $sharee,
],
];
} else {
$shareTypeResults[$sharee]['count']++;
}
}
$result = array_merge($result, array_values($shareTypeResults));
}
$top5 = array_slice(
$this->sortShareesByFrequency($result),
0,
5
);
$searchResult = new SearchResult();
foreach ($this->searchResultTypeMap as $int => $str) {
$searchResult->addResultSet(new SearchResultType($str), [], []);
foreach ($top5 as $x) {
if ($x['value']['shareType'] === $int) {
$searchResult->addResultSet(new SearchResultType($str), [], [$x]);
}
}
}
return $searchResult;
}
/**
* @NoAdminRequired
*
* @param string $itemType
* @return DataResponse
* @throws OCSBadRequestException
*/
public function findRecommended(string $itemType = null, $shareType = null): DataResponse {
$shareTypes = [
Share::SHARE_TYPE_USER,
];
if ($itemType === null) {
throw new OCSBadRequestException('Missing itemType');
} elseif ($itemType === 'file' || $itemType === 'folder') {
if ($this->shareManager->allowGroupSharing()) {
$shareTypes[] = Share::SHARE_TYPE_GROUP;
}
if ($this->isRemoteSharingAllowed($itemType)) {
$shareTypes[] = Share::SHARE_TYPE_REMOTE;
}
if ($this->isRemoteGroupSharingAllowed($itemType)) {
$shareTypes[] = Share::SHARE_TYPE_REMOTE_GROUP;
}
if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
$shareTypes[] = Share::SHARE_TYPE_EMAIL;
}
if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_ROOM)) {
$shareTypes[] = Share::SHARE_TYPE_ROOM;
}
} else {
$shareTypes[] = Share::SHARE_TYPE_GROUP;
$shareTypes[] = Share::SHARE_TYPE_EMAIL;
}
// FIXME: DI
if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
$shareTypes[] = Share::SHARE_TYPE_CIRCLE;
}
if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
sort($shareTypes);
} else if (is_numeric($shareType)) {
$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
sort($shareTypes);
}
return new DataResponse(
$this->getAllSharees($this->userId, $shareTypes)->asArray()
);
}
/**
* Method to get out the static call for better testing
*

View File

@ -46,14 +46,16 @@ $maxUploadFilesize = min($upload_max_filesize, $post_max_size);
</div>
<?php endif; ?>
<?php if ($_['showgridview'] && empty($_['dir']) === false) { ?>
<input type="checkbox" class="hidden-visually" id="showgridview"
<?php if($_['showgridview']) { ?>checked="checked" <?php } ?>/>
<label id="view-toggle" for="showgridview" class="button <?php p($_['showgridview'] ? 'icon-toggle-filelist' : 'icon-toggle-pictures') ?>"
title="<?php p($l->t('Toggle grid view'))?>"></label>
<?php } ?>
<?php if (!isset($_['hideFileList']) || (isset($_['hideFileList']) && $_['hideFileList'] === false)) { ?>
<!-- ONLY if this is a folder, we show the grid toggle button -->
<?php if (empty($_['dir']) === false) { ?>
<input type="checkbox" class="hidden-visually" id="showgridview"
<?php if($_['showgridview']) { ?>checked="checked" <?php } ?>/>
<label id="view-toggle" for="showgridview" class="button <?php p($_['showgridview'] ? 'icon-toggle-filelist' : 'icon-toggle-pictures') ?>"
title="<?php p($l->t('Toggle grid view'))?>"></label>
<?php } ?>
<!-- files listing -->
<div id="files-public-content">
<div id="preview">
<?php if (isset($_['folder'])): ?>

View File

@ -50,6 +50,9 @@ class ShareesAPIControllerTest extends TestCase {
/** @var ShareesAPIController */
protected $sharees;
/** @var string */
protected $uid;
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
protected $request;
@ -62,6 +65,7 @@ class ShareesAPIControllerTest extends TestCase {
protected function setUp() {
parent::setUp();
$this->uid = 'test123';
$this->request = $this->createMock(IRequest::class);
$this->shareManager = $this->createMock(IManager::class);
@ -74,6 +78,7 @@ class ShareesAPIControllerTest extends TestCase {
$this->collaboratorSearch = $this->createMock(ISearch::class);
$this->sharees = new ShareesAPIController(
$this->uid,
'files_sharing',
$this->request,
$configMock,
@ -243,6 +248,8 @@ class ShareesAPIControllerTest extends TestCase {
->method('allowGroupSharing')
->willReturn($allowGroupSharing);
/** @var string */
$uid = 'test123';
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */
@ -251,6 +258,7 @@ class ShareesAPIControllerTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */
$sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
->setConstructorArgs([
$uid,
'files_sharing',
$request,
$config,
@ -335,6 +343,8 @@ class ShareesAPIControllerTest extends TestCase {
$config->expects($this->never())
->method('getAppValue');
/** @var string */
$uid = 'test123';
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject $request */
$request = $this->createMock(IRequest::class);
/** @var IURLGenerator|\PHPUnit_Framework_MockObject_MockObject $urlGenerator */
@ -343,6 +353,7 @@ class ShareesAPIControllerTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject|\OCA\Files_Sharing\Controller\ShareesAPIController $sharees */
$sharees = $this->getMockBuilder('\OCA\Files_Sharing\Controller\ShareesAPIController')
->setConstructorArgs([
$uid,
'files_sharing',
$request,
$config,

View File

@ -60,8 +60,10 @@ $invert: luma($color-primary) > 0.6;
border: 1px solid nc-lighten($color-primary-text, 50%);
}
input.primary,
button.primary,
#alternative-logins li a {
background-color: $color-primary;
color: $color-primary-text;
}
a,
label,

View File

@ -22,6 +22,7 @@ OC.L10N.register(
"Your version is up to date." : "Votre version est à jour.",
"A non-default update server is in use to be checked for updates:" : "Un serveur spécifique est actuellement configuré pour la vérification des mises-à-jour :",
"Update channel:" : "Canal de mise à jour :",
"You can always update to a newer version. But you can never downgrade to a more stable version." : "Vous pouvez à tout moment mettre à jour votre instance Nextcloud vers une version plus récente. Vous ne pourrez cependant jamais revenir à une version antérieure en sélectionnant un canal plus stable.",
"Note that after a new release it can take some time before it shows up here. We roll out new versions spread out over time to our users and sometimes skip a version when issues are found." : "Veuillez noter qu'il peut s'écouler un certain temps entre la sortie d'une nouvelle version et sa disponibilité pour téléchargement et mise-à-jour ici, sur votre instance. Nous répartissons le déploiement des nouvelles versions Nextcloud dans le temps à l'ensemble de nos utilisateurs. Certaines versions mineures, présentant des bugs problématiques, peuvent être sautées.",
"Notify members of the following groups about available updates:" : "Notifier les membres des groupes suivants des mises à jours disponibles :",
"Only notification for app updates are available." : "Seules les notifications pour les mises à jour d'applications sont diponibles.",
@ -35,8 +36,11 @@ OC.L10N.register(
"<strong>All</strong> apps have an update for this version available" : "<strong>Toutes</strong> les applications ont une mise à jour disponible pour cette version",
"View changelog" : "Voir le journal des modifications",
"Stable" : "Stable",
"The most recent stable version. It is suited for regular use and will always update to the latest major version." : "La version stable la plus récente. Elle est adaptée pour une utilisation régulière et sera toujours mise à jour vers la dernière version majeure.",
"Production" : "Production",
"Will always provide the latest patch level, but not update to the next major release immediately. That update usually happens with the second minor release (x.0.2) and only if the instance is already on the latest minor version." : "Il fournira toujours le correctif le plus récent, mais ne mettra pas immédiatement à jour vers la version majeure suivante. Cette mise à jour se produit généralement avec la deuxième version mineure (x.0.2) et seulement si l'instance est déjà sur la dernière version mineure.",
"Beta" : "Beta",
"A pre-release version only for testing new features, not for production environments." : "Une version préliminaire utilisée seulement pour tester les nouvelles fonctionnalités, n'est pas adaptée dans un environnement de production.",
"_<strong>%n</strong> app has no update for this version available_::_<strong>%n</strong> apps have no update for this version available_" : ["<strong>%n</strong> application n'a pas de mise à jour disponible pour cette version","<strong>%n</strong> applications n'ont pas de mise à jour disponible pour cette version"],
"Could not start updater, please try the manual update" : "Impossible de démarrer le système de mise à jour, veuillez essayer de mettre à jour manuellement",
"A new version is available: %s" : "Une nouvelle version est disponible : %s",

View File

@ -20,6 +20,7 @@
"Your version is up to date." : "Votre version est à jour.",
"A non-default update server is in use to be checked for updates:" : "Un serveur spécifique est actuellement configuré pour la vérification des mises-à-jour :",
"Update channel:" : "Canal de mise à jour :",
"You can always update to a newer version. But you can never downgrade to a more stable version." : "Vous pouvez à tout moment mettre à jour votre instance Nextcloud vers une version plus récente. Vous ne pourrez cependant jamais revenir à une version antérieure en sélectionnant un canal plus stable.",
"Note that after a new release it can take some time before it shows up here. We roll out new versions spread out over time to our users and sometimes skip a version when issues are found." : "Veuillez noter qu'il peut s'écouler un certain temps entre la sortie d'une nouvelle version et sa disponibilité pour téléchargement et mise-à-jour ici, sur votre instance. Nous répartissons le déploiement des nouvelles versions Nextcloud dans le temps à l'ensemble de nos utilisateurs. Certaines versions mineures, présentant des bugs problématiques, peuvent être sautées.",
"Notify members of the following groups about available updates:" : "Notifier les membres des groupes suivants des mises à jours disponibles :",
"Only notification for app updates are available." : "Seules les notifications pour les mises à jour d'applications sont diponibles.",
@ -33,8 +34,11 @@
"<strong>All</strong> apps have an update for this version available" : "<strong>Toutes</strong> les applications ont une mise à jour disponible pour cette version",
"View changelog" : "Voir le journal des modifications",
"Stable" : "Stable",
"The most recent stable version. It is suited for regular use and will always update to the latest major version." : "La version stable la plus récente. Elle est adaptée pour une utilisation régulière et sera toujours mise à jour vers la dernière version majeure.",
"Production" : "Production",
"Will always provide the latest patch level, but not update to the next major release immediately. That update usually happens with the second minor release (x.0.2) and only if the instance is already on the latest minor version." : "Il fournira toujours le correctif le plus récent, mais ne mettra pas immédiatement à jour vers la version majeure suivante. Cette mise à jour se produit généralement avec la deuxième version mineure (x.0.2) et seulement si l'instance est déjà sur la dernière version mineure.",
"Beta" : "Beta",
"A pre-release version only for testing new features, not for production environments." : "Une version préliminaire utilisée seulement pour tester les nouvelles fonctionnalités, n'est pas adaptée dans un environnement de production.",
"_<strong>%n</strong> app has no update for this version available_::_<strong>%n</strong> apps have no update for this version available_" : ["<strong>%n</strong> application n'a pas de mise à jour disponible pour cette version","<strong>%n</strong> applications n'ont pas de mise à jour disponible pour cette version"],
"Could not start updater, please try the manual update" : "Impossible de démarrer le système de mise à jour, veuillez essayer de mettre à jour manuellement",
"A new version is available: %s" : "Une nouvelle version est disponible : %s",

View File

@ -30,6 +30,7 @@ OC.L10N.register(
"Checking apps for compatible updates" : "互換性のあるアップデートの有無を確認する",
"<strong>All</strong> apps have an update for this version available" : "<strong>すべての</strong> アプリにこのバージョンのアップデートがあります",
"View changelog" : "変更履歴を確認する",
"Beta" : "ベータ",
"_<strong>%n</strong> app has no update for this version available_::_<strong>%n</strong> apps have no update for this version available_" : ["<strong>%n</strong> アプリにこのバージョンのアップデートがありません"],
"Could not start updater, please try the manual update" : "アップデータを起動できませんでした。手動アップデートをお試しください",
"A new version is available: %s" : "新しいバージョンが利用可能: %s",

View File

@ -28,6 +28,7 @@
"Checking apps for compatible updates" : "互換性のあるアップデートの有無を確認する",
"<strong>All</strong> apps have an update for this version available" : "<strong>すべての</strong> アプリにこのバージョンのアップデートがあります",
"View changelog" : "変更履歴を確認する",
"Beta" : "ベータ",
"_<strong>%n</strong> app has no update for this version available_::_<strong>%n</strong> apps have no update for this version available_" : ["<strong>%n</strong> アプリにこのバージョンのアップデートがありません"],
"Could not start updater, please try the manual update" : "アップデータを起動できませんでした。手動アップデートをお試しください",
"A new version is available: %s" : "新しいバージョンが利用可能: %s",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Pravidlo pojmenování domovské složky uživatele",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Ponechte prázdné pro uživatelské jméno (výchozí). Jinak uveďte LDAP/AD parametr.",
"\"$home\" Placeholder Field" : "Výplňová kolonka „$home“",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home bude v nastavení externího úložiště nahrazeno hodnotou zadaného atributu",
"Internal Username" : "Interní uživatelské jméno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Ve výchozím nastavení bude interní uživatelské jméno vytvořeno z atributu UUID. To zajišťuje, že je uživatelské jméno unikátní a znaky nemusí být převáděny. Interní uživatelské jméno má omezení, podle kterého jsou povoleny jen následující znaky [ a-zA-Z0-9_.@- ]. Ostatní znaky jsou nahrazeny jejich protějšky z ASCII nebo prostě vynechány. Při konfliktech bude přidáno/zvýšeno číslo. Interní uživatelské jméno slouží pro interní identifikaci uživatele. Je také výchozím názvem domovského adresáře uživatele. Je také součástí URL, např. pro služby *DAV. Tímto nastavením může být výchozí chování změněno. Ponechte jej prázdné, chcete-li zachovat výchozí nastavení. Změny se projeví pouze u nově namapovaných (přidaných) uživatelů LDAP.",
"Internal Username Attribute:" : "Atribut interního uživatelského jména:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Pravidlo pojmenování domovské složky uživatele",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Ponechte prázdné pro uživatelské jméno (výchozí). Jinak uveďte LDAP/AD parametr.",
"\"$home\" Placeholder Field" : "Výplňová kolonka „$home“",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home bude v nastavení externího úložiště nahrazeno hodnotou zadaného atributu",
"Internal Username" : "Interní uživatelské jméno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Ve výchozím nastavení bude interní uživatelské jméno vytvořeno z atributu UUID. To zajišťuje, že je uživatelské jméno unikátní a znaky nemusí být převáděny. Interní uživatelské jméno má omezení, podle kterého jsou povoleny jen následující znaky [ a-zA-Z0-9_.@- ]. Ostatní znaky jsou nahrazeny jejich protějšky z ASCII nebo prostě vynechány. Při konfliktech bude přidáno/zvýšeno číslo. Interní uživatelské jméno slouží pro interní identifikaci uživatele. Je také výchozím názvem domovského adresáře uživatele. Je také součástí URL, např. pro služby *DAV. Tímto nastavením může být výchozí chování změněno. Ponechte jej prázdné, chcete-li zachovat výchozí nastavení. Změny se projeví pouze u nově namapovaných (přidaných) uživatelů LDAP.",
"Internal Username Attribute:" : "Atribut interního uživatelského jména:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Benennungsregel für das Home-Verzeichnis des Benutzers",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Ohne Eingabe wird der Benutzername (Standard) verwendet. Anderenfall trage ein LDAP/AD-Attribut ein.",
"\"$home\" Placeholder Field" : "\"$home\" Platzhalter-Feld",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home in der Konfiguration eines extern angeschlossenen Speichers wird mit dem Wert des angegebenen Attributs ersetzt",
"Internal Username" : "Interner Benutzername",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Standardmäßig wird der interne Benutzername aus dem UUID-Atribut erstellt. So wird sichergestellt, dass der Benutzername einmalig ist und Zeichen nicht konvertiert werden müssen. Für den internen Benutzernamen sind nur folgende Zeichen zulässig: [ a-zA-Z0-9_.@- ]. Andere Zeichen werden mit ihrer ASCII-Entsprechung ersetzt oder einfach weggelassen. Bei Kollisionen wird eine Nummer hinzugefügt/erhöht. Der interne Benutzername wird verwandt, um den Benutzer intern zu identifizieren. Er ist ausserdem der Standardname für den Stamm-Ordner des Benutzers. Darüber hinaus ist er Teil der URLs für den Zugriff, zum Bespiel für alle *DAV-Dienste. Mit dieser Einstellung, kann das Standardverhalten geändert werden. Für die Standardeinstellung, lasse das Eingabefeld leer. Änderungen wirken sich nur auf neu eingetragene (hinzugefügte) LDAP-Benutzer aus.",
"Internal Username Attribute:" : "Attribut für interne Benutzernamen:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Benennungsregel für das Home-Verzeichnis des Benutzers",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Ohne Eingabe wird der Benutzername (Standard) verwendet. Anderenfall trage ein LDAP/AD-Attribut ein.",
"\"$home\" Placeholder Field" : "\"$home\" Platzhalter-Feld",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home in der Konfiguration eines extern angeschlossenen Speichers wird mit dem Wert des angegebenen Attributs ersetzt",
"Internal Username" : "Interner Benutzername",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Standardmäßig wird der interne Benutzername aus dem UUID-Atribut erstellt. So wird sichergestellt, dass der Benutzername einmalig ist und Zeichen nicht konvertiert werden müssen. Für den internen Benutzernamen sind nur folgende Zeichen zulässig: [ a-zA-Z0-9_.@- ]. Andere Zeichen werden mit ihrer ASCII-Entsprechung ersetzt oder einfach weggelassen. Bei Kollisionen wird eine Nummer hinzugefügt/erhöht. Der interne Benutzername wird verwandt, um den Benutzer intern zu identifizieren. Er ist ausserdem der Standardname für den Stamm-Ordner des Benutzers. Darüber hinaus ist er Teil der URLs für den Zugriff, zum Bespiel für alle *DAV-Dienste. Mit dieser Einstellung, kann das Standardverhalten geändert werden. Für die Standardeinstellung, lasse das Eingabefeld leer. Änderungen wirken sich nur auf neu eingetragene (hinzugefügte) LDAP-Benutzer aus.",
"Internal Username Attribute:" : "Attribut für interne Benutzernamen:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Benennungsregel für das Home-Verzeichnis des Benutzers",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Ohne Eingabe wird der Benutzername (Standard) verwendet. Anderenfalls tragen Sie bitte ein LDAP/AD-Attribut ein.",
"\"$home\" Placeholder Field" : "\"$home\" Platzhalter-Feld",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home in der Konfiguration eines extern angeschlossenen Speichers wird mit dem Wert des angegebenen Attributs ersetzt",
"Internal Username" : "Interner Benutzername",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Standardmäßig wird der interne Benutzername aus dem UUID-Atribut erstellt. So wird sichergestellt, dass der Benutzername einmalig ist und Zeichen nicht konvertiert werden müssen. Für den internen Benutzernamen sind nur folgende Zeichen zulässig: [ a-zA-Z0-9_.@- ]. Andere Zeichen werden mit ihrer ASCII-Entsprechung ersetzt oder einfach weggelassen. Bei Kollisionen wird eine Nummer hinzugefügt/erhöht. Der interne Benutzername wird verwandt, um den Benutzer intern zu identifizieren. Er ist ausserdem der Standardname für den Stamm-Ordner des Benutzers. Darüber hinaus ist er Teil der URLs für den Zugriff, zum Bespiel für alle *DAV-Dienste. Mit dieser Einstellung, kann das Standardverhalten geändert werden. Für die Standardeinstellung, lassen Sie das Eingabefeld leer. Änderungen wirken sich nur auf neu eingetragene (hinzugefügte) LDAP-Benutzer aus.",
"Internal Username Attribute:" : "Interne Eigenschaften des Benutzers:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Benennungsregel für das Home-Verzeichnis des Benutzers",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Ohne Eingabe wird der Benutzername (Standard) verwendet. Anderenfalls tragen Sie bitte ein LDAP/AD-Attribut ein.",
"\"$home\" Placeholder Field" : "\"$home\" Platzhalter-Feld",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home in der Konfiguration eines extern angeschlossenen Speichers wird mit dem Wert des angegebenen Attributs ersetzt",
"Internal Username" : "Interner Benutzername",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Standardmäßig wird der interne Benutzername aus dem UUID-Atribut erstellt. So wird sichergestellt, dass der Benutzername einmalig ist und Zeichen nicht konvertiert werden müssen. Für den internen Benutzernamen sind nur folgende Zeichen zulässig: [ a-zA-Z0-9_.@- ]. Andere Zeichen werden mit ihrer ASCII-Entsprechung ersetzt oder einfach weggelassen. Bei Kollisionen wird eine Nummer hinzugefügt/erhöht. Der interne Benutzername wird verwandt, um den Benutzer intern zu identifizieren. Er ist ausserdem der Standardname für den Stamm-Ordner des Benutzers. Darüber hinaus ist er Teil der URLs für den Zugriff, zum Bespiel für alle *DAV-Dienste. Mit dieser Einstellung, kann das Standardverhalten geändert werden. Für die Standardeinstellung, lassen Sie das Eingabefeld leer. Änderungen wirken sich nur auf neu eingetragene (hinzugefügte) LDAP-Benutzer aus.",
"Internal Username Attribute:" : "Interne Eigenschaften des Benutzers:",

View File

@ -161,7 +161,6 @@ OC.L10N.register(
"Set the user's email from their LDAP attribute. Leave it empty for default behaviour." : "Establecer el correo electrónico del usuario con base en el atributo LDAP. Dejelo vacío para el comportamiento predeterminado. ",
"User Home Folder Naming Rule" : "Regla de Nomenclatura para la Carpeta Inicio del Usuario",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Dejar vacío para el nombre de usuario (predeterminado). En otro caso, especifique un atributo LDAP/AD.",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home en una configuración de almacenamiento externo será reemplazado por el valor del atributo especificado",
"Internal Username" : "Nombre de usuario interno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Por defecto, el nombre de usuario interno se creará con base en el atributo UUID. Esto asegura que el nombre de usuario sea único y que los caracteres no tengan que ser convertidos. El nombre de usuario intenro tiene la restricción de que sólo los siguienes caracteres están permitidos: [ a-zA-Z0-9_.@- ]. El resto de los caracteres son reemplazados con su correspondencia ASCII o simplemente se omiten. En caso de colisiones, se agregará/ incrementará un numero. El nombre de usuario interno se usa para identificar a un usuario internamente. Adicionalmente es el nombre predeterminado para la carpeta de inicio. También es parte de las URLs remotas, por ejemplo, para todos los servicios *DAV. Con este ajuste se puede anular el comportamiento predeterminado. Mantengalo vacío para mantener el comportamiento predeterminado. Los cambios surtiran efecto sólo en los usuarios mapeados (agregados) nuevos a LDAP. ",
"Internal Username Attribute:" : "Atributo de nombre de usuario Interno:",

View File

@ -159,7 +159,6 @@
"Set the user's email from their LDAP attribute. Leave it empty for default behaviour." : "Establecer el correo electrónico del usuario con base en el atributo LDAP. Dejelo vacío para el comportamiento predeterminado. ",
"User Home Folder Naming Rule" : "Regla de Nomenclatura para la Carpeta Inicio del Usuario",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Dejar vacío para el nombre de usuario (predeterminado). En otro caso, especifique un atributo LDAP/AD.",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home en una configuración de almacenamiento externo será reemplazado por el valor del atributo especificado",
"Internal Username" : "Nombre de usuario interno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Por defecto, el nombre de usuario interno se creará con base en el atributo UUID. Esto asegura que el nombre de usuario sea único y que los caracteres no tengan que ser convertidos. El nombre de usuario intenro tiene la restricción de que sólo los siguienes caracteres están permitidos: [ a-zA-Z0-9_.@- ]. El resto de los caracteres son reemplazados con su correspondencia ASCII o simplemente se omiten. En caso de colisiones, se agregará/ incrementará un numero. El nombre de usuario interno se usa para identificar a un usuario internamente. Adicionalmente es el nombre predeterminado para la carpeta de inicio. También es parte de las URLs remotas, por ejemplo, para todos los servicios *DAV. Con este ajuste se puede anular el comportamiento predeterminado. Mantengalo vacío para mantener el comportamiento predeterminado. Los cambios surtiran efecto sólo en los usuarios mapeados (agregados) nuevos a LDAP. ",
"Internal Username Attribute:" : "Atributo de nombre de usuario Interno:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Regra de nomeado do cartafol do usuario",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Deixar baleiro para o nome de usuario (predeterminado). Noutro caso, especifique un atributo LDAP/AD.",
"\"$home\" Placeholder Field" : "Campo de marcador de posición «$home»",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "Nunha configuración de almacenamento externo substituirase $home polo valor do atributo especificado",
"Internal Username" : "Nome interno de usuario",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "De xeito predeterminado, o nome interno de usuario crearase a partires do atributo UUID. Isto asegura que o nome de usuario é único e non é necesario converter os caracteres. O nome interno de usuario ten a restrición de que só se admiten estes caracteres: [ a-zA-Z0-9_.@- ]. Outros caracteres son substituídos pola súa correspondencia ASCII ou simplemente omitidos. En caso de colisións engadirase/incrementarase un número. O nome interno de usuario usase para identificar internamente a un usuario. É tamén o nome predeterminado do cartafol de inicio do usuario. Tamén é parte dos URL remotos, por exemplo para todos os servizos *DAV. Con esta configuración, pódese anular o comportamento predeterminado. Déixeo baleiro para usar o comportamento predeterminado. Os cambios terán efecto só nos usuarios LDAP signados (engadidos) após os cambios.",
"Internal Username Attribute:" : "Atributo do nome interno de usuario:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Regra de nomeado do cartafol do usuario",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Deixar baleiro para o nome de usuario (predeterminado). Noutro caso, especifique un atributo LDAP/AD.",
"\"$home\" Placeholder Field" : "Campo de marcador de posición «$home»",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "Nunha configuración de almacenamento externo substituirase $home polo valor do atributo especificado",
"Internal Username" : "Nome interno de usuario",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "De xeito predeterminado, o nome interno de usuario crearase a partires do atributo UUID. Isto asegura que o nome de usuario é único e non é necesario converter os caracteres. O nome interno de usuario ten a restrición de que só se admiten estes caracteres: [ a-zA-Z0-9_.@- ]. Outros caracteres son substituídos pola súa correspondencia ASCII ou simplemente omitidos. En caso de colisións engadirase/incrementarase un número. O nome interno de usuario usase para identificar internamente a un usuario. É tamén o nome predeterminado do cartafol de inicio do usuario. Tamén é parte dos URL remotos, por exemplo para todos os servizos *DAV. Con esta configuración, pódese anular o comportamento predeterminado. Déixeo baleiro para usar o comportamento predeterminado. Os cambios terán efecto só nos usuarios LDAP signados (engadidos) após os cambios.",
"Internal Username Attribute:" : "Atributo do nome interno de usuario:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Regola di assegnazione del nome della cartella utente",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Lascia vuoto per il nome utente (predefinito). Altrimenti, specifica un attributo LDAP/AD.",
"\"$home\" Placeholder Field" : "Segnaposto \"$home\"",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home nella configurazione di un'archiviazione esterna sarà sostituita con il valore dell'attributo specificato",
"Internal Username" : "Nome utente interno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "In modo predefinito, il nome utente interno sarà creato dall'attributo UUID. Ciò assicura che il nome utente sia univoco e che non sia necessario convertire i caratteri. Il nome utente interno consente l'uso di determinati caratteri: [ a-zA-Z0-9_.@- ]. Altri caratteri sono sostituiti con il corrispondente ASCII o sono semplicemente omessi. In caso di conflitto, sarà aggiunto/incrementato un numero. Il nome utente interno è utilizzato per identificare un utente internamente. Rappresenta, inoltre, il nome predefinito per la cartella home dell'utente in ownCloud. Costituisce anche una parte di URL remoti, ad esempio per tutti i servizi *DAV. Con questa impostazione, il comportamento predefinito può essere scavalcato. Lascialo vuoto per ottenere il comportamento predefinito. Le modifiche avranno effetto solo sui nuovo utenti LDAP associati (aggiunti).",
"Internal Username Attribute:" : "Attributo nome utente interno:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Regola di assegnazione del nome della cartella utente",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Lascia vuoto per il nome utente (predefinito). Altrimenti, specifica un attributo LDAP/AD.",
"\"$home\" Placeholder Field" : "Segnaposto \"$home\"",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home nella configurazione di un'archiviazione esterna sarà sostituita con il valore dell'attributo specificato",
"Internal Username" : "Nome utente interno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "In modo predefinito, il nome utente interno sarà creato dall'attributo UUID. Ciò assicura che il nome utente sia univoco e che non sia necessario convertire i caratteri. Il nome utente interno consente l'uso di determinati caratteri: [ a-zA-Z0-9_.@- ]. Altri caratteri sono sostituiti con il corrispondente ASCII o sono semplicemente omessi. In caso di conflitto, sarà aggiunto/incrementato un numero. Il nome utente interno è utilizzato per identificare un utente internamente. Rappresenta, inoltre, il nome predefinito per la cartella home dell'utente in ownCloud. Costituisce anche una parte di URL remoti, ad esempio per tutti i servizi *DAV. Con questa impostazione, il comportamento predefinito può essere scavalcato. Lascialo vuoto per ottenere il comportamento predefinito. Le modifiche avranno effetto solo sui nuovo utenti LDAP associati (aggiunti).",
"Internal Username Attribute:" : "Attributo nome utente interno:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Gebruikers Home map naamgevingsregel",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Laat leeg voor de gebruikersnaam (standaard). Of specificeer een LDAP/AD attribuut.",
"\"$home\" Placeholder Field" : "\"$home\" Plaatshouder veld",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home in een externe opslag configuratie wordt vervangen door de waarde van het gespecificeerde attribuut",
"Internal Username" : "Interne gebruikersnaam",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Standaard wordt de interne gebruikersnaam afgeleid van het UUID attribuut. dat zorgt ervoor dat de gebruikersnaam uniek is en dat tekens niet hoeven te worden geconverteerd. De interne gebruikersnaam heeft de beperking dat alleen deze tekens zijn toegestaan: [ a-zA-Z0-9_.@- ]. Andere tekens worden vervangen door hun overeenkomstige ASCII-waarde of simpelweg weggelaten. Bij conflicten wordt een nummer toegevoegd/verhoogd. De interne gebruikersnaam wordt gebruikt om een gebruiker intern te identificeren. Het is ook de standaardnaam voor de thuis-map van de gebruiker. Het is ook onderdeel van de externe URLs, bijvoorbeeld voor alle *DAV services. Met deze instelling kan het standaardgedrag worden overschreven. Laat het leeg voor de standaardwerkwijze. Wijzigingen hebben alleen effect voor nieuw gekoppelde (toegevoegde) LDAP gebruikers.",
"Internal Username Attribute:" : "Interne gebruikersnaam attribuut:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Gebruikers Home map naamgevingsregel",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Laat leeg voor de gebruikersnaam (standaard). Of specificeer een LDAP/AD attribuut.",
"\"$home\" Placeholder Field" : "\"$home\" Plaatshouder veld",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home in een externe opslag configuratie wordt vervangen door de waarde van het gespecificeerde attribuut",
"Internal Username" : "Interne gebruikersnaam",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Standaard wordt de interne gebruikersnaam afgeleid van het UUID attribuut. dat zorgt ervoor dat de gebruikersnaam uniek is en dat tekens niet hoeven te worden geconverteerd. De interne gebruikersnaam heeft de beperking dat alleen deze tekens zijn toegestaan: [ a-zA-Z0-9_.@- ]. Andere tekens worden vervangen door hun overeenkomstige ASCII-waarde of simpelweg weggelaten. Bij conflicten wordt een nummer toegevoegd/verhoogd. De interne gebruikersnaam wordt gebruikt om een gebruiker intern te identificeren. Het is ook de standaardnaam voor de thuis-map van de gebruiker. Het is ook onderdeel van de externe URLs, bijvoorbeeld voor alle *DAV services. Met deze instelling kan het standaardgedrag worden overschreven. Laat het leeg voor de standaardwerkwijze. Wijzigingen hebben alleen effect voor nieuw gekoppelde (toegevoegde) LDAP gebruikers.",
"Internal Username Attribute:" : "Interne gebruikersnaam attribuut:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Regra de nomeação de pasta de usuário Home",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Deixe vazio para nome de usuário (padrão). Caso contrário, especifique um atributo LDAP/AD.",
"\"$home\" Placeholder Field" : "Campo Reservado \"$home\"",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home em uma configuração de armazenamento externo será substituído pelo valor do atributo especificado",
"Internal Username" : "Nome de usuário interno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Por padrão, um nome de usuário interno será criado a partir de um atributo UUID. Isso garante que o nome de usuário seja único e estes caracteres não precisam ser convertidos. um nome de usuário interno possui a restrição que somente estes caracteres são permitdos: [ a-zA-Z0-9_.@- ]. Outros caracteres serão substituidos por seus correspondentes ASCII ou simplesmente omitidos. Em caso de coincidências, um número será adicionado/incrementado. O nome de usuário interno é utilizado para identificar o usuário internamente. Também é o nome padrão da pasta principal do usuário. Também é uma parte das URL's remotas, por exemplo, para todos os serviços *DAV. Com esta configuração, o comportamento padrão pode ser alterado. Deixe em branco para que assuma o comportamento padrão. Alterações terão efeito apenas em novos usuários LDAP mapeados (adicionados).",
"Internal Username Attribute:" : "Atributo Interno de Nome de Usuário:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Regra de nomeação de pasta de usuário Home",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Deixe vazio para nome de usuário (padrão). Caso contrário, especifique um atributo LDAP/AD.",
"\"$home\" Placeholder Field" : "Campo Reservado \"$home\"",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home em uma configuração de armazenamento externo será substituído pelo valor do atributo especificado",
"Internal Username" : "Nome de usuário interno",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Por padrão, um nome de usuário interno será criado a partir de um atributo UUID. Isso garante que o nome de usuário seja único e estes caracteres não precisam ser convertidos. um nome de usuário interno possui a restrição que somente estes caracteres são permitdos: [ a-zA-Z0-9_.@- ]. Outros caracteres serão substituidos por seus correspondentes ASCII ou simplesmente omitidos. Em caso de coincidências, um número será adicionado/incrementado. O nome de usuário interno é utilizado para identificar o usuário internamente. Também é o nome padrão da pasta principal do usuário. Também é uma parte das URL's remotas, por exemplo, para todos os serviços *DAV. Com esta configuração, o comportamento padrão pode ser alterado. Deixe em branco para que assuma o comportamento padrão. Alterações terão efeito apenas em novos usuários LDAP mapeados (adicionados).",
"Internal Username Attribute:" : "Atributo Interno de Nome de Usuário:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Правило именовања корисничке фасцикле",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Оставите празно за корисничко име (подразумевано). У супротном, наведите особину LDAP/AD.",
"\"$home\" Placeholder Field" : "Резервисано место за поље „$home“",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home ће се у подешавању спољног складишта заменити са вредношћу задатог атрибута",
"Internal Username" : "Интерно корисничко име:",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Подразумевано се интерно корисничко име креира од UUID атрибута. Тиме се гарантује да се корисничко име јединствено и да карактери не морају да се конвертују. Интерно корисничко име има ограничења да су дозвољени само следећи карактери: [ a-zA-Z0-9_.@- ]. Остали карактери ће или бити замењени ASCII еквивалентима или ће бити прескочени. Ако се деси поклапање са постојећим корисничким именом, додаће се број на крај имена. Интерно корисничко име се користи да идентификује корисника интерно. Такође се користи и као подразумевано име за име корисничку фасцикле, а и део је удаљених адреса, нпр. свих *DAV сервиса. Уз помоћ овог подешавања, може да се промени подразумевано понашање. Оставите га празним за подразумевано понашање. Промене ће се тицати само новомапираних (додатих) LDAP корисника.",
"Internal Username Attribute:" : "Интерни параметри корисничког имена:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Правило именовања корисничке фасцикле",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Оставите празно за корисничко име (подразумевано). У супротном, наведите особину LDAP/AD.",
"\"$home\" Placeholder Field" : "Резервисано место за поље „$home“",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home ће се у подешавању спољног складишта заменити са вредношћу задатог атрибута",
"Internal Username" : "Интерно корисничко име:",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Подразумевано се интерно корисничко име креира од UUID атрибута. Тиме се гарантује да се корисничко име јединствено и да карактери не морају да се конвертују. Интерно корисничко име има ограничења да су дозвољени само следећи карактери: [ a-zA-Z0-9_.@- ]. Остали карактери ће или бити замењени ASCII еквивалентима или ће бити прескочени. Ако се деси поклапање са постојећим корисничким именом, додаће се број на крај имена. Интерно корисничко име се користи да идентификује корисника интерно. Такође се користи и као подразумевано име за име корисничку фасцикле, а и део је удаљених адреса, нпр. свих *DAV сервиса. Уз помоћ овог подешавања, може да се промени подразумевано понашање. Оставите га празним за подразумевано понашање. Промене ће се тицати само новомапираних (додатих) LDAP корисника.",
"Internal Username Attribute:" : "Интерни параметри корисничког имена:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Namnregel för hemkatalog",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Lämnas tomt för användarnamn (standard). Ange annars ett LDAP-/AD-attribut.",
"\"$home\" Placeholder Field" : "\"$home\" Platshållare-fält",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home i en extern lagringskonfiguration kommer ersättas med värdet av det angivna attributet",
"Internal Username" : "Internt användarnamn",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Som standard kommer de interna användarnamnen skapas från UUID-attributen. Det säkerställer att användarnamnet är unikt och att tecken inte behöver konverteras. Det interna användarnamnet har begränsningen att bara dessa tecken tillåts: [ a-zA-Z0-9_.@- ]. Andra tecken kommer att ersättas med deras korresponderande ASCII-kod eller utelämnas. Vid kollisioner kommer ett nummer läggas till/ökas. Det interna användarnamnet används för att identifiera en användare internt. Det är också standardnamnet för användarens hemmapp. Det är också en del av externa URL'er, till exempel för alla *DAV-tjänster. Med denna inställning, kan standardbeteendet bli överskrivet. Lämna det tomt för standardbeteende. Ändringar kommer att bara gälla för nya mappningar (tillagda) LDAP-användare.",
"Internal Username Attribute:" : "Internt användarnamnsattribut:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Namnregel för hemkatalog",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Lämnas tomt för användarnamn (standard). Ange annars ett LDAP-/AD-attribut.",
"\"$home\" Placeholder Field" : "\"$home\" Platshållare-fält",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "$home i en extern lagringskonfiguration kommer ersättas med värdet av det angivna attributet",
"Internal Username" : "Internt användarnamn",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Som standard kommer de interna användarnamnen skapas från UUID-attributen. Det säkerställer att användarnamnet är unikt och att tecken inte behöver konverteras. Det interna användarnamnet har begränsningen att bara dessa tecken tillåts: [ a-zA-Z0-9_.@- ]. Andra tecken kommer att ersättas med deras korresponderande ASCII-kod eller utelämnas. Vid kollisioner kommer ett nummer läggas till/ökas. Det interna användarnamnet används för att identifiera en användare internt. Det är också standardnamnet för användarens hemmapp. Det är också en del av externa URL'er, till exempel för alla *DAV-tjänster. Med denna inställning, kan standardbeteendet bli överskrivet. Lämna det tomt för standardbeteende. Ändringar kommer att bara gälla för nya mappningar (tillagda) LDAP-användare.",
"Internal Username Attribute:" : "Internt användarnamnsattribut:",

View File

@ -177,7 +177,6 @@ OC.L10N.register(
"User Home Folder Naming Rule" : "Kullanıcı Ana Klasörünü Adlandırma Kuralı",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Kullanıcı adının kullanılması için boş bırakın (varsayılan) ya da bir LDAP/AD özniteliği belirtin.",
"\"$home\" Placeholder Field" : "\"$home\" Yer Belirleyici Alanı",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "Bir dış depolama yapılandırmasında $home yerine belirtilen öznitelik kullanılır",
"Internal Username" : "İç Kullanıcı Adı",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Varsayılan olarak, iç kullanıcı adı UUID özniteliğinden oluşturulur. Böylece kullanıcı adının eşsiz olması ve dönüştürülmesi gereken karakterler içermediğinden emin olunur. İç kullanıcı adında kısıtlaması yalnız şu karakterleri kullanılabilir: [ a-zA-Z0-9_.@- ]. Diğer karakterler ASCII karşılıklarına dönüştürülür ya da yok sayılır. Çakışmalarda ada bir sayı eklenir. İç kullanıcı adı bir kullanıcıyı içsel olarak belirlemeye yarar. Aynı zamanda kullanıcı ana klasörünün varsayılan adı olarak da kullanılır. İnternet adreslerinin, örneğin *DAV servislerinin bir parçasıdır. Bu seçenek ile varsayılan davranış değiştirilebilir. Varsayılan davranışı kullanmak için boş bırakın. Değişiklikler yalnız yeni eşleştirilecek (eklenecek) LDAP kullanıcılarını etkiler.",
"Internal Username Attribute:" : "İç Kullanıcı Adı Özniteliği:",

View File

@ -175,7 +175,6 @@
"User Home Folder Naming Rule" : "Kullanıcı Ana Klasörünü Adlandırma Kuralı",
"Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute." : "Kullanıcı adının kullanılması için boş bırakın (varsayılan) ya da bir LDAP/AD özniteliği belirtin.",
"\"$home\" Placeholder Field" : "\"$home\" Yer Belirleyici Alanı",
"$home in an external storage configuration will replaced with the value of the specified attribute" : "Bir dış depolama yapılandırmasında $home yerine belirtilen öznitelik kullanılır",
"Internal Username" : "İç Kullanıcı Adı",
"By default the internal username will be created from the UUID attribute. It makes sure that the username is unique and characters do not need to be converted. The internal username has the restriction that only these characters are allowed: [ a-zA-Z0-9_.@- ]. Other characters are replaced with their ASCII correspondence or simply omitted. On collisions a number will be added/increased. The internal username is used to identify a user internally. It is also the default name for the user home folder. It is also a part of remote URLs, for instance for all *DAV services. With this setting, the default behavior can be overridden. Leave it empty for default behavior. Changes will have effect only on newly mapped (added) LDAP users." : "Varsayılan olarak, iç kullanıcı adı UUID özniteliğinden oluşturulur. Böylece kullanıcı adının eşsiz olması ve dönüştürülmesi gereken karakterler içermediğinden emin olunur. İç kullanıcı adında kısıtlaması yalnız şu karakterleri kullanılabilir: [ a-zA-Z0-9_.@- ]. Diğer karakterler ASCII karşılıklarına dönüştürülür ya da yok sayılır. Çakışmalarda ada bir sayı eklenir. İç kullanıcı adı bir kullanıcıyı içsel olarak belirlemeye yarar. Aynı zamanda kullanıcı ana klasörünün varsayılan adı olarak da kullanılır. İnternet adreslerinin, örneğin *DAV servislerinin bir parçasıdır. Bu seçenek ile varsayılan davranış değiştirilebilir. Varsayılan davranışı kullanmak için boş bırakın. Değişiklikler yalnız yeni eşleştirilecek (eklenecek) LDAP kullanıcılarını etkiler.",
"Internal Username Attribute:" : "İç Kullanıcı Adı Özniteliği:",

View File

@ -108,7 +108,7 @@ style('user_ldap', 'settings');
<p><label for="ldap_quota_def"><?php p($l->t('Quota Default'));?></label><input type="text" id="ldap_quota_def" name="ldap_quota_def" data-default="<?php p($_['ldap_quota_def_default']); ?>" title="<?php p($l->t('Override default quota for LDAP users who do not have a quota set in the Quota Field.'));?>" /></p>
<p><label for="ldap_email_attr"><?php p($l->t('Email Field'));?></label><input type="text" id="ldap_email_attr" name="ldap_email_attr" data-default="<?php p($_['ldap_email_attr_default']); ?>" title="<?php p($l->t('Set the user\'s email from their LDAP attribute. Leave it empty for default behaviour.'));?>" /></p>
<p><label for="home_folder_naming_rule"><?php p($l->t('User Home Folder Naming Rule'));?></label><input type="text" id="home_folder_naming_rule" name="home_folder_naming_rule" title="<?php p($l->t('Leave empty for user name (default). Otherwise, specify an LDAP/AD attribute.'));?>" data-default="<?php p($_['home_folder_naming_rule_default']); ?>" /></p>
<p><label for="ldap_ext_storage_home_attribute"> <?php p($l->t('"$home" Placeholder Field')); ?></label><input type="text" id="ldap_ext_storage_home_attribute" name="ldap_ext_storage_home_attribute" title="<?php p($l->t('$home in an external storage configuration will replaced with the value of the specified attribute')); ?>" data-default="<?php p($_['ldap_ext_storage_home_attribute_default']); ?>"></p>
<p><label for="ldap_ext_storage_home_attribute"> <?php p($l->t('"$home" Placeholder Field')); ?></label><input type="text" id="ldap_ext_storage_home_attribute" name="ldap_ext_storage_home_attribute" title="<?php p($l->t('$home in an external storage configuration will be replaced with the value of the specified attribute')); ?>" data-default="<?php p($_['ldap_ext_storage_home_attribute_default']); ?>"></p>
</div>
</div>
<?php print_unescaped($_['settingControls']); ?>

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Kontrola %s neexistuje",
"Check %s is invalid" : "Kontrola %s je neplatná",
"Check #%s does not exist" : "Kontrola č. %s neexistuje",
"Tag management" : "Správa štítků",
"Files workflow engine" : "Engine práce se soubory",
"Open documentation" : "Otevřít dokumentaci",
"Loading…" : "Načítání…",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Kontrola %s neexistuje",
"Check %s is invalid" : "Kontrola %s je neplatná",
"Check #%s does not exist" : "Kontrola č. %s neexistuje",
"Tag management" : "Správa štítků",
"Files workflow engine" : "Engine práce se soubory",
"Open documentation" : "Otevřít dokumentaci",
"Loading…" : "Načítání…",

View File

@ -23,10 +23,10 @@ OC.L10N.register(
"less or equals" : "weniger oder gleich",
"greater or equals" : "größer oder gleich",
"greater" : "größer",
"File system tag" : "Dateisystem-Tag",
"is tagged with" : "hat den Tag",
"is not tagged with" : "hat nicht den Tag",
"Select tag…" : "Wähle einen Tag…",
"File system tag" : "Dateisystem-Schlagwort",
"is tagged with" : "hat das Schlagwort",
"is not tagged with" : "ist nicht verschlagwortet mit",
"Select tag…" : "Wähle ein Schlagwort…",
"Request remote address" : "IP Adresse der Anfrage",
"matches IPv4" : "entspricht IPv4",
"does not match IPv4" : "entspricht nicht IPv4",
@ -53,7 +53,7 @@ OC.L10N.register(
"The given operator is invalid" : "Der angegebene Operator ist ungültig",
"The given regular expression is invalid" : "Der angegebene Reguläre Ausdruck ist ungültig",
"The given file size is invalid" : "Die angegebene Dateigröße ist ungültig",
"The given tag id is invalid" : "Die angegebene Tag ID ist ungültig",
"The given tag id is invalid" : "Die angegebene Schlagwort-ID ist ungültig",
"The given IP range is invalid" : "Der angegebene IP-Bereich ist ungültig",
"The given IP range is not valid for IPv4" : "Der angegebene IP-Bereich ist ungültig für IPv4",
"The given IP range is not valid for IPv6" : "Der angegebene IP-Bereich ist ungültig für IPv6",
@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Die Prüfung %s existiert nicht",
"Check %s is invalid" : "Die Prüfung %s ist ungültig",
"Check #%s does not exist" : "Die Prüfung #%s existiert nicht",
"Tag management" : "Schlagwortverwaltung",
"Files workflow engine" : "Datei-Workflow-Engine",
"Open documentation" : "Dokumentation öffnen",
"Loading…" : "Laden…",

View File

@ -21,10 +21,10 @@
"less or equals" : "weniger oder gleich",
"greater or equals" : "größer oder gleich",
"greater" : "größer",
"File system tag" : "Dateisystem-Tag",
"is tagged with" : "hat den Tag",
"is not tagged with" : "hat nicht den Tag",
"Select tag…" : "Wähle einen Tag…",
"File system tag" : "Dateisystem-Schlagwort",
"is tagged with" : "hat das Schlagwort",
"is not tagged with" : "ist nicht verschlagwortet mit",
"Select tag…" : "Wähle ein Schlagwort…",
"Request remote address" : "IP Adresse der Anfrage",
"matches IPv4" : "entspricht IPv4",
"does not match IPv4" : "entspricht nicht IPv4",
@ -51,7 +51,7 @@
"The given operator is invalid" : "Der angegebene Operator ist ungültig",
"The given regular expression is invalid" : "Der angegebene Reguläre Ausdruck ist ungültig",
"The given file size is invalid" : "Die angegebene Dateigröße ist ungültig",
"The given tag id is invalid" : "Die angegebene Tag ID ist ungültig",
"The given tag id is invalid" : "Die angegebene Schlagwort-ID ist ungültig",
"The given IP range is invalid" : "Der angegebene IP-Bereich ist ungültig",
"The given IP range is not valid for IPv4" : "Der angegebene IP-Bereich ist ungültig für IPv4",
"The given IP range is not valid for IPv6" : "Der angegebene IP-Bereich ist ungültig für IPv6",
@ -66,6 +66,7 @@
"Check %s does not exist" : "Die Prüfung %s existiert nicht",
"Check %s is invalid" : "Die Prüfung %s ist ungültig",
"Check #%s does not exist" : "Die Prüfung #%s existiert nicht",
"Tag management" : "Schlagwortverwaltung",
"Files workflow engine" : "Datei-Workflow-Engine",
"Open documentation" : "Dokumentation öffnen",
"Loading…" : "Laden…",

View File

@ -23,10 +23,10 @@ OC.L10N.register(
"less or equals" : "weniger oder gleich",
"greater or equals" : "größer oder gleich",
"greater" : "größer",
"File system tag" : "Dateisystem-Tag",
"is tagged with" : "hat den Tag",
"is not tagged with" : "hat nicht den Tag",
"Select tag…" : "Wählen Sie einen Tag…",
"File system tag" : "Dateisystem-Schlagwort",
"is tagged with" : "hat das Schlagwort",
"is not tagged with" : "ist nicht verschlagwortet mit",
"Select tag…" : "Wählen Sie ein Schlagwort…",
"Request remote address" : "IP Adresse der Anfrage",
"matches IPv4" : "entspricht IPv4",
"does not match IPv4" : "entspricht nicht IPv4",
@ -53,7 +53,7 @@ OC.L10N.register(
"The given operator is invalid" : "Der angegebene Operator ist falsch",
"The given regular expression is invalid" : "Der angegebene reguläre Ausdruck ist falsch",
"The given file size is invalid" : "Die angegebene Dateigröße ist ungültig",
"The given tag id is invalid" : "Die angegebene Tag-ID ist ungültig",
"The given tag id is invalid" : "Die angegebene Schlagwort-ID ist ungültig",
"The given IP range is invalid" : "Der angegebene IP-Bereich ist falsch",
"The given IP range is not valid for IPv4" : "Der angegebene IP-Bereich ist für IPv4 ungültig",
"The given IP range is not valid for IPv6" : "Der angegebene IP-Bereich ist für IPv6 ungültig",
@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Die Prüfung %s existiert nicht",
"Check %s is invalid" : "Die Prüfung %s ist ungültig",
"Check #%s does not exist" : "Die Prüfung #%s existiert nicht",
"Tag management" : "Schlagwortverwaltung",
"Files workflow engine" : "Datei-Workflow-Engine",
"Open documentation" : "Dokumentation öffnen",
"Loading…" : "Laden…",

View File

@ -21,10 +21,10 @@
"less or equals" : "weniger oder gleich",
"greater or equals" : "größer oder gleich",
"greater" : "größer",
"File system tag" : "Dateisystem-Tag",
"is tagged with" : "hat den Tag",
"is not tagged with" : "hat nicht den Tag",
"Select tag…" : "Wählen Sie einen Tag…",
"File system tag" : "Dateisystem-Schlagwort",
"is tagged with" : "hat das Schlagwort",
"is not tagged with" : "ist nicht verschlagwortet mit",
"Select tag…" : "Wählen Sie ein Schlagwort…",
"Request remote address" : "IP Adresse der Anfrage",
"matches IPv4" : "entspricht IPv4",
"does not match IPv4" : "entspricht nicht IPv4",
@ -51,7 +51,7 @@
"The given operator is invalid" : "Der angegebene Operator ist falsch",
"The given regular expression is invalid" : "Der angegebene reguläre Ausdruck ist falsch",
"The given file size is invalid" : "Die angegebene Dateigröße ist ungültig",
"The given tag id is invalid" : "Die angegebene Tag-ID ist ungültig",
"The given tag id is invalid" : "Die angegebene Schlagwort-ID ist ungültig",
"The given IP range is invalid" : "Der angegebene IP-Bereich ist falsch",
"The given IP range is not valid for IPv4" : "Der angegebene IP-Bereich ist für IPv4 ungültig",
"The given IP range is not valid for IPv6" : "Der angegebene IP-Bereich ist für IPv6 ungültig",
@ -66,6 +66,7 @@
"Check %s does not exist" : "Die Prüfung %s existiert nicht",
"Check %s is invalid" : "Die Prüfung %s ist ungültig",
"Check #%s does not exist" : "Die Prüfung #%s existiert nicht",
"Tag management" : "Schlagwortverwaltung",
"Files workflow engine" : "Datei-Workflow-Engine",
"Open documentation" : "Dokumentation öffnen",
"Loading…" : "Laden…",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Kontrolo %s ne ekzistas",
"Check %s is invalid" : "Kontrolo %s ne validas",
"Check #%s does not exist" : "Kontrolo n-ro %s ne ekzistas",
"Tag management" : "Etikeda administrado",
"Files workflow engine" : "Modulo de dosiera laborfluo",
"Open documentation" : "Malfermi dokumentaron",
"Loading…" : "Ŝargante...",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Kontrolo %s ne ekzistas",
"Check %s is invalid" : "Kontrolo %s ne validas",
"Check #%s does not exist" : "Kontrolo n-ro %s ne ekzistas",
"Tag management" : "Etikeda administrado",
"Files workflow engine" : "Modulo de dosiera laborfluo",
"Open documentation" : "Malfermi dokumentaron",
"Loading…" : "Ŝargante...",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Non existe a proba %s",
"Check %s is invalid" : "A proba %s é incorrecta",
"Check #%s does not exist" : "Non existe a proba num. %s ",
"Tag management" : "Xestión de etiquetas",
"Files workflow engine" : "Motor de fluxo de traballo de ficheiros",
"Open documentation" : "Documentación aberta",
"Loading…" : "Cargando…",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Non existe a proba %s",
"Check %s is invalid" : "A proba %s é incorrecta",
"Check #%s does not exist" : "Non existe a proba num. %s ",
"Tag management" : "Xestión de etiquetas",
"Files workflow engine" : "Motor de fluxo de traballo de ficheiros",
"Open documentation" : "Documentación aberta",
"Loading…" : "Cargando…",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Il controllo %s non esiste",
"Check %s is invalid" : "Il controllo %s non è valido",
"Check #%s does not exist" : "Il controllo #%s non esiste",
"Tag management" : "Gestione etichette",
"Files workflow engine" : "Motore delle procedure dei file",
"Open documentation" : "Apri documentazione",
"Loading…" : "Caricamento in corso...",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Il controllo %s non esiste",
"Check %s is invalid" : "Il controllo %s non è valido",
"Check #%s does not exist" : "Il controllo #%s non esiste",
"Tag management" : "Gestione etichette",
"Files workflow engine" : "Motore delle procedure dei file",
"Open documentation" : "Apri documentazione",
"Loading…" : "Caricamento in corso...",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Controleer: %s bestaat niet",
"Check %s is invalid" : "Controleer: %s is ongeldig",
"Check #%s does not exist" : "Controleer: #%s bestaat niet",
"Tag management" : "Tagbeheer",
"Files workflow engine" : "Betanden workflow engine",
"Open documentation" : "Open documentatie",
"Loading…" : "Laden...",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Controleer: %s bestaat niet",
"Check %s is invalid" : "Controleer: %s is ongeldig",
"Check #%s does not exist" : "Controleer: #%s bestaat niet",
"Tag management" : "Tagbeheer",
"Files workflow engine" : "Betanden workflow engine",
"Open documentation" : "Open documentatie",
"Loading…" : "Laden...",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Sprawdź, czy %s nie istnieje",
"Check %s is invalid" : "Sprawdź, czy %s jest nieprawidłowy",
"Check #%s does not exist" : "Sprawdź, czy #%s nie istnieje",
"Tag management" : "Zarządzanie tagami",
"Files workflow engine" : "Pliki silnika workflow",
"Open documentation" : "Otwórz dokumentację",
"Loading…" : "Wczytywanie…",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Sprawdź, czy %s nie istnieje",
"Check %s is invalid" : "Sprawdź, czy %s jest nieprawidłowy",
"Check #%s does not exist" : "Sprawdź, czy #%s nie istnieje",
"Tag management" : "Zarządzanie tagami",
"Files workflow engine" : "Pliki silnika workflow",
"Open documentation" : "Otwórz dokumentację",
"Loading…" : "Wczytywanie…",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Verifique se %s não existe",
"Check %s is invalid" : "Verifique se %s é inválido",
"Check #%s does not exist" : "Verifique se %s não existe",
"Tag management" : "Gerenciamento de rótulos",
"Files workflow engine" : "Sistema de fluxo de trabalho de arquivos",
"Open documentation" : "Abrir documentação",
"Loading…" : "Carregando...",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Verifique se %s não existe",
"Check %s is invalid" : "Verifique se %s é inválido",
"Check #%s does not exist" : "Verifique se %s não existe",
"Tag management" : "Gerenciamento de rótulos",
"Files workflow engine" : "Sistema de fluxo de trabalho de arquivos",
"Open documentation" : "Abrir documentação",
"Loading…" : "Carregando...",

View File

@ -68,6 +68,7 @@ OC.L10N.register(
"Check %s does not exist" : "Проверите да ли %s постоји",
"Check %s is invalid" : "Проверите да ли је %s исправно",
"Check #%s does not exist" : "Проверите да ли #%s постоји",
"Tag management" : "Управљање ознакама",
"Files workflow engine" : "Датотеке за мотор процеса рада",
"Open documentation" : "Отвори документацију",
"Loading…" : "Учитавање…",

View File

@ -66,6 +66,7 @@
"Check %s does not exist" : "Проверите да ли %s постоји",
"Check %s is invalid" : "Проверите да ли је %s исправно",
"Check #%s does not exist" : "Проверите да ли #%s постоји",
"Tag management" : "Управљање ознакама",
"Files workflow engine" : "Датотеке за мотор процеса рада",
"Open documentation" : "Отвори документацију",
"Loading…" : "Учитавање…",

View File

@ -59,6 +59,7 @@ $expectedFiles = [
'index.html',
'index.php',
'lib',
'Makefile',
'occ',
'ocs',
'ocs-provider',

View File

@ -48,8 +48,7 @@ export TEST_SERVER_FED_URL="http://localhost:$PORT_FED/ocs/"
if [ "$INSTALLED" == "true" ]; then
#Enable external storage app
$OCC app:enable files_external
$OCC app:enable user_ldap
$OCC app:enable files_external user_ldap
mkdir -p work/local_storage
OUTPUT_CREATE_STORAGE=`$OCC files_external:create local_storage local null::null -c datadir=$PWD/work/local_storage`
@ -71,8 +70,7 @@ if [ "$INSTALLED" == "true" ]; then
$OCC files_external:delete -y $ID_STORAGE
#Disable external storage app
$OCC app:disable files_external
$OCC app:disable user_ldap
$OCC app:disable files_external user_ldap
fi
if [ -z $HIDE_OC_LOGS ]; then

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\BackgroundJobs;
use OC\Core\Db\LoginFlowV2Mapper;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
class CleanupLoginFlowV2 extends TimedJob {
/** @var LoginFlowV2Mapper */
private $loginFlowV2Mapper;
public function __construct(ITimeFactory $time, LoginFlowV2Mapper $loginFlowV2Mapper) {
parent::__construct($time);
$this->loginFlowV2Mapper = $loginFlowV2Mapper;
$this->setInterval(3600);
}
protected function run($argument) {
$this->loginFlowV2Mapper->cleanup();
}
}

View File

@ -36,39 +36,52 @@ use Symfony\Component\Console\Output\OutputInterface;
class Disable extends Command implements CompletionAwareInterface {
/** @var IAppManager */
protected $manager;
protected $appManager;
/** @var int */
protected $exitCode = 0;
/**
* @param IAppManager $manager
* @param IAppManager $appManager
*/
public function __construct(IAppManager $manager) {
public function __construct(IAppManager $appManager) {
parent::__construct();
$this->manager = $manager;
$this->appManager = $appManager;
}
protected function configure() {
protected function configure(): void {
$this
->setName('app:disable')
->setDescription('disable an app')
->addArgument(
'app-id',
InputArgument::REQUIRED,
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'disable the specified app'
);
}
protected function execute(InputInterface $input, OutputInterface $output) {
$appId = $input->getArgument('app-id');
if ($this->manager->isInstalled($appId)) {
try {
$this->manager->disableApp($appId);
$output->writeln($appId . ' disabled');
} catch(\Exception $e) {
$output->writeln($e->getMessage());
return 2;
}
} else {
$appIds = $input->getArgument('app-id');
foreach ($appIds as $appId) {
$this->disableApp($appId, $output);
}
return $this->exitCode;
}
private function disableApp(string $appId, OutputInterface $output): void {
if ($this->appManager->isInstalled($appId) === false) {
$output->writeln('No such app enabled: ' . $appId);
return;
}
try {
$this->appManager->disableApp($appId);
$output->writeln($appId . ' disabled');
} catch (\Exception $e) {
$output->writeln($e->getMessage());
$this->exitCode = 2;
}
}
@ -88,7 +101,7 @@ class Disable extends Command implements CompletionAwareInterface {
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'app-id') {
return array_diff(\OC_App::getEnabledApps(true, true), $this->manager->getAlwaysEnabledApps());
return array_diff(\OC_App::getEnabledApps(true, true), $this->appManager->getAlwaysEnabledApps());
}
return [];
}

View File

@ -26,8 +26,11 @@
namespace OC\Core\Command\App;
use OC\Installer;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\IGroup;
use OCP\IGroupManager;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Command\Command;
@ -39,23 +42,31 @@ use Symfony\Component\Console\Output\OutputInterface;
class Enable extends Command implements CompletionAwareInterface {
/** @var IAppManager */
protected $manager;
protected $appManager;
/** @var IGroupManager */
protected $groupManager;
/** @var int */
protected $exitCode = 0;
/**
* @param IAppManager $manager
* @param IAppManager $appManager
* @param IGroupManager $groupManager
*/
public function __construct(IAppManager $manager) {
public function __construct(IAppManager $appManager, IGroupManager $groupManager) {
parent::__construct();
$this->manager = $manager;
$this->appManager = $appManager;
$this->groupManager = $groupManager;
}
protected function configure() {
protected function configure(): void {
$this
->setName('app:enable')
->setDescription('enable an app')
->addArgument(
'app-id',
InputArgument::REQUIRED,
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'enable the specified app'
)
->addOption(
@ -63,28 +74,70 @@ class Enable extends Command implements CompletionAwareInterface {
'g',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'enable the app only for a list of groups'
)
;
);
}
protected function execute(InputInterface $input, OutputInterface $output) {
$appId = $input->getArgument('app-id');
$appIds = $input->getArgument('app-id');
$groups = $this->resolveGroupIds($input->getOption('groups'));
if (!\OC_App::getAppPath($appId)) {
foreach ($appIds as $appId) {
$this->enableApp($appId, $groups, $output);
}
return $this->exitCode;
}
/**
* @param string $appId
* @param array $groupIds
* @param OutputInterface $output
*/
private function enableApp(string $appId, array $groupIds, OutputInterface $output): void {
$groupNames = array_map(function (IGroup $group) {
return $group->getDisplayName();
}, $groupIds);
try {
/** @var Installer $installer */
$installer = \OC::$server->query(Installer::class);
if (false === $installer->isDownloaded($appId)) {
$installer->downloadApp($appId);
}
$installer->installApp($appId);
if ($groupIds === []) {
$this->appManager->enableApp($appId);
$output->writeln($appId . ' enabled');
} else {
$this->appManager->enableAppForGroups($appId, $groupIds);
$output->writeln($appId . ' enabled for groups: ' . implode(', ', $groupNames));
}
} catch (AppPathNotFoundException $e) {
$output->writeln($appId . ' not found');
return 1;
$this->exitCode = 1;
} catch (\Exception $e) {
$output->writeln($e->getMessage());
$this->exitCode = 1;
}
}
$groups = $input->getOption('groups');
$appClass = new \OC_App();
if (empty($groups)) {
$appClass->enable($appId);
$output->writeln($appId . ' enabled');
} else {
$appClass->enable($appId, $groups);
$output->writeln($appId . ' enabled for groups: ' . implode(', ', $groups));
/**
* @param array $groupIds
* @return array
*/
private function resolveGroupIds(array $groupIds): array {
$groups = [];
foreach ($groupIds as $groupId) {
$group = $this->groupManager->get($groupId);
if ($group instanceof IGroup) {
$groups[] = $group;
}
}
return 0;
return $groups;
}
/**
@ -94,9 +147,9 @@ class Enable extends Command implements CompletionAwareInterface {
*/
public function completeOptionValues($optionName, CompletionContext $context) {
if ($optionName === 'groups') {
return array_map(function(IGroup $group) {
return array_map(function (IGroup $group) {
return $group->getGID();
}, \OC::$server->getGroupManager()->search($context->getCurrentWord()));
}, $this->groupManager->search($context->getCurrentWord()));
}
return [];
}

View File

@ -89,7 +89,7 @@ class DecryptAll extends Command {
*/
protected function forceMaintenanceAndTrashbin() {
$this->wasTrashbinEnabled = $this->appManager->isEnabledForUser('files_trashbin');
$this->wasMaintenanceModeEnabled = $this->config->getSystemValue('maintenance', false);
$this->wasMaintenanceModeEnabled = $this->config->getSystemValueBool('maintenance');
$this->config->setSystemValue('maintenance', true);
$this->appManager->disableApp('files_trashbin');
}

View File

@ -78,7 +78,7 @@ class EncryptAll extends Command {
*/
protected function forceMaintenanceAndTrashbin() {
$this->wasTrashbinEnabled = $this->appManager->isEnabledForUser('files_trashbin');
$this->wasMaintenanceModeEnabled = $this->config->getSystemValue('maintenance', false);
$this->wasMaintenanceModeEnabled = $this->config->getSystemValueBool('maintenance');
$this->config->setSystemValue('maintenance', true);
$this->appManager->disableApp('files_trashbin');
}

View File

@ -59,7 +59,7 @@ class Mode extends Command {
}
protected function execute(InputInterface $input, OutputInterface $output) {
$maintenanceMode = $this->config->getSystemValue('maintenance', false);
$maintenanceMode = $this->config->getSystemValueBool('maintenance');
if ($input->getOption('on')) {
if ($maintenanceMode === false) {
$this->config->setSystemValue('maintenance', true);

View File

@ -106,7 +106,7 @@ class Repair extends Command {
}
}
$maintenanceMode = $this->config->getSystemValue('maintenance', false);
$maintenanceMode = $this->config->getSystemValueBool('maintenance');
$this->config->setSystemValue('maintenance', true);
$this->progress = new ProgressBar($output);

View File

@ -180,7 +180,7 @@ class Upgrade extends Command {
$dispatcher->addListener('\OC\Repair::info', $repairListener);
$dispatcher->addListener('\OC\Repair::warning', $repairListener);
$dispatcher->addListener('\OC\Repair::error', $repairListener);
$updater->listen('\OC\Updater', 'maintenanceEnabled', function () use($output) {
$output->writeln('<info>Turned on maintenance mode</info>');
@ -264,7 +264,7 @@ class Upgrade extends Command {
}
return self::ERROR_SUCCESS;
} else if($this->config->getSystemValue('maintenance', false)) {
} else if($this->config->getSystemValueBool('maintenance')) {
//Possible scenario: Nextcloud core is updated but an app failed
$output->writeln('<warning>Nextcloud is in maintenance mode</warning>');
$output->write('<comment>Maybe an upgrade is already in process. Please check the '

View File

@ -0,0 +1,299 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Controller;
use OC\Core\Db\LoginFlowV2;
use OC\Core\Exception\LoginFlowV2NotFoundException;
use OC\Core\Service\LoginFlowV2Service;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\StandaloneTemplateResponse;
use OCP\Defaults;
use OCP\IL10N;
use OCP\IRequest;
use OCP\ISession;
use OCP\IURLGenerator;
use OCP\Security\ISecureRandom;
class ClientFlowLoginV2Controller extends Controller {
private const tokenName = 'client.flow.v2.login.token';
private const stateName = 'client.flow.v2.state.token';
/** @var LoginFlowV2Service */
private $loginFlowV2Service;
/** @var IURLGenerator */
private $urlGenerator;
/** @var ISession */
private $session;
/** @var ISecureRandom */
private $random;
/** @var Defaults */
private $defaults;
/** @var string */
private $userId;
/** @var IL10N */
private $l10n;
public function __construct(string $appName,
IRequest $request,
LoginFlowV2Service $loginFlowV2Service,
IURLGenerator $urlGenerator,
ISession $session,
ISecureRandom $random,
Defaults $defaults,
?string $userId,
IL10N $l10n) {
parent::__construct($appName, $request);
$this->loginFlowV2Service = $loginFlowV2Service;
$this->urlGenerator = $urlGenerator;
$this->session = $session;
$this->random = $random;
$this->defaults = $defaults;
$this->userId = $userId;
$this->l10n = $l10n;
}
/**
* @NoCSRFRequired
* @PublicPage
*/
public function poll(string $token): JSONResponse {
try {
$creds = $this->loginFlowV2Service->poll($token);
} catch (LoginFlowV2NotFoundException $e) {
return new JSONResponse([], Http::STATUS_NOT_FOUND);
}
return new JSONResponse($creds);
}
/**
* @NoCSRFRequired
* @PublicPage
* @UseSession
*/
public function landing(string $token): Response {
if (!$this->loginFlowV2Service->startLoginFlow($token)) {
return $this->loginTokenForbiddenResponse();
}
$this->session->set(self::tokenName, $token);
return new RedirectResponse(
$this->urlGenerator->linkToRouteAbsolute('core.ClientFlowLoginV2.showAuthPickerPage')
);
}
/**
* @NoCSRFRequired
* @PublicPage
* @UseSession
*/
public function showAuthPickerPage(): StandaloneTemplateResponse {
try {
$flow = $this->getFlowByLoginToken();
} catch (LoginFlowV2NotFoundException $e) {
return $this->loginTokenForbiddenResponse();
}
$stateToken = $this->random->generate(
64,
ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS
);
$this->session->set(self::stateName, $stateToken);
return new StandaloneTemplateResponse(
$this->appName,
'loginflowv2/authpicker',
[
'client' => $flow->getClientName(),
'instanceName' => $this->defaults->getName(),
'urlGenerator' => $this->urlGenerator,
'stateToken' => $stateToken,
],
'guest'
);
}
/**
* @NoAdminRequired
* @UseSession
* @NoCSRFRequired
* @NoSameSiteCookieRequired
*/
public function grantPage(string $stateToken): StandaloneTemplateResponse {
if(!$this->isValidStateToken($stateToken)) {
return $this->stateTokenForbiddenResponse();
}
try {
$flow = $this->getFlowByLoginToken();
} catch (LoginFlowV2NotFoundException $e) {
return $this->loginTokenForbiddenResponse();
}
return new StandaloneTemplateResponse(
$this->appName,
'loginflowv2/grant',
[
'client' => $flow->getClientName(),
'instanceName' => $this->defaults->getName(),
'urlGenerator' => $this->urlGenerator,
'stateToken' => $stateToken,
],
'guest'
);
}
/**
* @NoAdminRequired
* @UseSession
*/
public function generateAppPassword(string $stateToken): Response {
if(!$this->isValidStateToken($stateToken)) {
return $this->stateTokenForbiddenResponse();
}
try {
$this->getFlowByLoginToken();
} catch (LoginFlowV2NotFoundException $e) {
return $this->loginTokenForbiddenResponse();
}
$loginToken = $this->session->get(self::tokenName);
// Clear session variables
$this->session->remove(self::tokenName);
$this->session->remove(self::stateName);
$sessionId = $this->session->getId();
$result = $this->loginFlowV2Service->flowDone($loginToken, $sessionId, $this->getServerPath(), $this->userId);
if ($result) {
return new StandaloneTemplateResponse(
$this->appName,
'loginflowv2/done',
[],
'guest'
);
}
$response = new StandaloneTemplateResponse(
$this->appName,
'403',
[
'message' => $this->l10n->t('Could not complete login'),
],
'guest'
);
$response->setStatus(Http::STATUS_FORBIDDEN);
return $response;
}
/**
* @NoCSRFRequired
* @PublicPage
*/
public function init(): JSONResponse {
// Get client user agent
$userAgent = $this->request->getHeader('USER_AGENT');
$tokens = $this->loginFlowV2Service->createTokens($userAgent);
$data = [
'poll' => [
'token' => $tokens->getPollToken(),
'endpoint' => $this->urlGenerator->linkToRouteAbsolute('core.ClientFlowLoginV2.poll')
],
'login' => $this->urlGenerator->linkToRouteAbsolute('core.ClientFlowLoginV2.landing', ['token' => $tokens->getLoginToken()]),
];
return new JSONResponse($data);
}
private function isValidStateToken(string $stateToken): bool {
$currentToken = $this->session->get(self::stateName);
if(!is_string($stateToken) || !is_string($currentToken)) {
return false;
}
return hash_equals($currentToken, $stateToken);
}
private function stateTokenForbiddenResponse(): StandaloneTemplateResponse {
$response = new StandaloneTemplateResponse(
$this->appName,
'403',
[
'message' => $this->l10n->t('State token does not match'),
],
'guest'
);
$response->setStatus(Http::STATUS_FORBIDDEN);
return $response;
}
/**
* @return LoginFlowV2
* @throws LoginFlowV2NotFoundException
*/
private function getFlowByLoginToken(): LoginFlowV2 {
$currentToken = $this->session->get(self::tokenName);
if(!is_string($currentToken)) {
throw new LoginFlowV2NotFoundException('Login token not set in session');
}
return $this->loginFlowV2Service->getByLoginToken($currentToken);
}
private function loginTokenForbiddenResponse(): StandaloneTemplateResponse {
$response = new StandaloneTemplateResponse(
$this->appName,
'403',
[
'message' => $this->l10n->t('Your login token is invalid or has expired'),
],
'guest'
);
$response->setStatus(Http::STATUS_FORBIDDEN);
return $response;
}
private function getServerPath(): string {
$serverPostfix = '';
if (strpos($this->request->getRequestUri(), '/index.php') !== false) {
$serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/index.php'));
} else if (strpos($this->request->getRequestUri(), '/login/v2') !== false) {
$serverPostfix = substr($this->request->getRequestUri(), 0, strpos($this->request->getRequestUri(), '/login/v2'));
}
$protocol = $this->request->getServerProtocol();
return $protocol . '://' . $this->request->getServerHost() . $serverPostfix;
}
}

View File

@ -0,0 +1,71 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Data;
class LoginFlowV2Credentials implements \JsonSerializable {
/** @var string */
private $server;
/** @var string */
private $loginName;
/** @var string */
private $appPassword;
public function __construct(string $server, string $loginName, string $appPassword) {
$this->server = $server;
$this->loginName = $loginName;
$this->appPassword = $appPassword;
}
/**
* @return string
*/
public function getServer(): string {
return $this->server;
}
/**
* @return string
*/
public function getLoginName(): string {
return $this->loginName;
}
/**
* @return string
*/
public function getAppPassword(): string {
return $this->appPassword;
}
public function jsonSerialize(): array {
return [
'server' => $this->server,
'loginName' => $this->loginName,
'appPassword' => $this->appPassword,
];
}
}

View File

@ -0,0 +1,47 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Data;
class LoginFlowV2Tokens {
/** @var string */
private $loginToken;
/** @var string */
private $pollToken;
public function __construct(string $loginToken, string $pollToken) {
$this->loginToken = $loginToken;
$this->pollToken = $pollToken;
}
public function getPollToken(): string {
return $this->pollToken;
}
public function getLoginToken(): string {
return $this->loginToken;
}
}

85
core/Db/LoginFlowV2.php Normal file
View File

@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Db;
use OCP\AppFramework\Db\Entity;
/**
* @method int getTimestamp()
* @method void setTimestamp(int $timestamp)
* @method int getStarted()
* @method void setStarted(int $started)
* @method string getPollToken()
* @method void setPollToken(string $token)
* @method string getLoginToken()
* @method void setLoginToken(string $token)
* @method string getPublicKey()
* @method void setPublicKey(string $key)
* @method string getPrivateKey()
* @method void setPrivateKey(string $key)
* @method string getClientName()
* @method void setClientName(string $clientName)
* @method string getLoginName()
* @method void setLoginName(string $loginName)
* @method string getServer()
* @method void setServer(string $server)
* @method string getAppPassword()
* @method void setAppPassword(string $appPassword)
*/
class LoginFlowV2 extends Entity {
/** @var int */
protected $timestamp;
/** @var int */
protected $started;
/** @var string */
protected $pollToken;
/** @var string */
protected $loginToken;
/** @var string */
protected $publicKey;
/** @var string */
protected $privateKey;
/** @var string */
protected $clientName;
/** @var string */
protected $loginName;
/** @var string */
protected $server;
/** @var string */
protected $appPassword;
public function __construct() {
$this->addType('timestamp', 'int');
$this->addType('started', 'int');
$this->addType('pollToken', 'string');
$this->addType('loginToken', 'string');
$this->addType('publicKey', 'string');
$this->addType('privateKey', 'string');
$this->addType('clientName', 'string');
$this->addType('loginName', 'string');
$this->addType('server', 'string');
$this->addType('appPassword', 'string');
}
}

View File

@ -0,0 +1,100 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Db;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\QBMapper;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IDBConnection;
class LoginFlowV2Mapper extends QBMapper {
private const lifetime = 1200;
/** @var ITimeFactory */
private $timeFactory;
public function __construct(IDBConnection $db, ITimeFactory $timeFactory) {
parent::__construct($db, 'login_flow_v2', LoginFlowV2::class);
$this->timeFactory = $timeFactory;
}
/**
* @param string $pollToken
* @return LoginFlowV2
* @throws DoesNotExistException
*/
public function getByPollToken(string $pollToken): LoginFlowV2 {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('poll_token', $qb->createNamedParameter($pollToken))
);
$entity = $this->findEntity($qb);
return $this->validateTimestamp($entity);
}
/**
* @param string $loginToken
* @return LoginFlowV2
* @throws DoesNotExistException
*/
public function getByLoginToken(string $loginToken): LoginFlowV2 {
$qb = $this->db->getQueryBuilder();
$qb->select('*')
->from($this->getTableName())
->where(
$qb->expr()->eq('login_token', $qb->createNamedParameter($loginToken))
);
$entity = $this->findEntity($qb);
return $this->validateTimestamp($entity);
}
public function cleanup(): void {
$qb = $this->db->getQueryBuilder();
$qb->delete($this->getTableName())
->where(
$qb->expr()->lt('timestamp', $qb->createNamedParameter($this->timeFactory->getTime() - self::lifetime))
);
$qb->execute();
}
/**
* @param LoginFlowV2 $flowV2
* @return LoginFlowV2
* @throws DoesNotExistException
*/
private function validateTimestamp(LoginFlowV2 $flowV2): LoginFlowV2 {
if ($flowV2->getTimestamp() < ($this->timeFactory->getTime() - self::lifetime)) {
$this->delete($flowV2);
throw new DoesNotExistException('Token expired');
}
return $flowV2;
}
}

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Exception;
class LoginFlowV2NotFoundException extends \Exception {
}

View File

@ -95,7 +95,8 @@ class TwoFactorMiddleware extends Middleware {
if ($this->userSession->isLoggedIn()) {
$user = $this->userSession->getUser();
if ($this->twoFactorManager->isTwoFactorAuthenticated($user)) {
if ($this->session->exists('app_password') || $this->twoFactorManager->isTwoFactorAuthenticated($user)) {
$this->checkTwoFactor($controller, $methodName, $user);
} else if ($controller instanceof TwoFactorChallengeController) {
// Allow access to the two-factor controllers only if two-factor authentication

View File

@ -523,7 +523,7 @@ class Version13000Date20170718121200 extends SimpleMigrationStep {
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['token'], 'authtoken_token_index');
$table->addIndex(['last_activity'], 'authtoken_last_activity_index');
$table->addIndex(['last_activity'], 'authtoken_last_activity_idx');
}
if (!$schema->hasTable('bruteforce_attempts')) {

View File

@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Migrations;
use Closure;
use Doctrine\DBAL\Types\Type;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\SimpleMigrationStep;
use OCP\Migration\IOutput;
class Version16000Date20190212081545 extends SimpleMigrationStep {
/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
* @return null|ISchemaWrapper
*/
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->createTable('login_flow_v2');
$table->addColumn('id', Type::BIGINT, [
'autoincrement' => true,
'notnull' => true,
'length' => 20,
'unsigned' => true,
]);
$table->addColumn('timestamp', Type::BIGINT, [
'notnull' => true,
'length' => 20,
'unsigned' => true,
]);
$table->addColumn('started', Type::SMALLINT, [
'notnull' => true,
'length' => 1,
'unsigned' => true,
'default' => 0,
]);
$table->addColumn('poll_token', Type::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('login_token', Type::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('public_key', Type::TEXT, [
'notnull' => true,
'length' => 32768,
]);
$table->addColumn('private_key', Type::TEXT, [
'notnull' => true,
'length' => 32768,
]);
$table->addColumn('client_name', Type::STRING, [
'notnull' => true,
'length' => 255,
]);
$table->addColumn('login_name', Type::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('server', Type::STRING, [
'notnull' => false,
'length' => 255,
]);
$table->addColumn('app_password', Type::STRING, [
'notnull' => false,
'length' => 1024,
]);
$table->setPrimaryKey(['id']);
$table->addUniqueIndex(['poll_token']);
$table->addUniqueIndex(['login_token']);
$table->addIndex(['timestamp']);
return $schema;
}
}

View File

@ -0,0 +1,260 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2019, Roeland Jago Douma <roeland@famdouma.nl>
*
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Service;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OC\Core\Data\LoginFlowV2Credentials;
use OC\Core\Data\LoginFlowV2Tokens;
use OC\Core\Db\LoginFlowV2;
use OC\Core\Db\LoginFlowV2Mapper;
use OC\Core\Exception\LoginFlowV2NotFoundException;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IConfig;
use OCP\ILogger;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
class LoginFlowV2Service {
/** @var LoginFlowV2Mapper */
private $mapper;
/** @var ISecureRandom */
private $random;
/** @var ITimeFactory */
private $time;
/** @var IConfig */
private $config;
/** @var ICrypto */
private $crypto;
/** @var ILogger */
private $logger;
/** @var IProvider */
private $tokenProvider;
public function __construct(LoginFlowV2Mapper $mapper,
ISecureRandom $random,
ITimeFactory $time,
IConfig $config,
ICrypto $crypto,
ILogger $logger,
IProvider $tokenProvider) {
$this->mapper = $mapper;
$this->random = $random;
$this->time = $time;
$this->config = $config;
$this->crypto = $crypto;
$this->logger = $logger;
$this->tokenProvider = $tokenProvider;
}
/**
* @param string $pollToken
* @return LoginFlowV2Credentials
* @throws LoginFlowV2NotFoundException
*/
public function poll(string $pollToken): LoginFlowV2Credentials {
try {
$data = $this->mapper->getByPollToken($this->hashToken($pollToken));
} catch (DoesNotExistException $e) {
throw new LoginFlowV2NotFoundException('Invalid token');
}
$loginName = $data->getLoginName();
$server = $data->getServer();
$appPassword = $data->getAppPassword();
if ($loginName === null || $server === null || $appPassword === null) {
throw new LoginFlowV2NotFoundException('Token not yet ready');
}
// Remove the data from the DB
$this->mapper->delete($data);
try {
// Decrypt the apptoken
$privateKey = $this->crypto->decrypt($data->getPrivateKey(), $pollToken);
$appPassword = $this->decryptPassword($data->getAppPassword(), $privateKey);
} catch (\Exception $e) {
throw new LoginFlowV2NotFoundException('Apptoken could not be decrypted');
}
return new LoginFlowV2Credentials($server, $loginName, $appPassword);
}
/**
* @param string $loginToken
* @return LoginFlowV2
* @throws LoginFlowV2NotFoundException
*/
public function getByLoginToken(string $loginToken): LoginFlowV2 {
try {
return $this->mapper->getByLoginToken($loginToken);
} catch (DoesNotExistException $e) {
throw new LoginFlowV2NotFoundException('Login token invalid');
}
}
/**
* @param string $loginToken
* @return bool returns true if the start was successfull. False if not.
*/
public function startLoginFlow(string $loginToken): bool {
try {
$data = $this->mapper->getByLoginToken($loginToken);
} catch (DoesNotExistException $e) {
return false;
}
if ($data->getStarted() !== 0) {
return false;
}
$data->setStarted(1);
$this->mapper->update($data);
return true;
}
/**
* @param string $loginToken
* @param string $sessionId
* @param string $server
* @param string $userId
* @return bool true if the flow was successfully completed false otherwise
*/
public function flowDone(string $loginToken, string $sessionId, string $server, string $userId): bool {
try {
$data = $this->mapper->getByLoginToken($loginToken);
} catch (DoesNotExistException $e) {
return false;
}
try {
$sessionToken = $this->tokenProvider->getToken($sessionId);
$loginName = $sessionToken->getLoginName();
try {
$password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
} catch (PasswordlessTokenException $ex) {
$password = null;
}
} catch (InvalidTokenException $ex) {
return false;
}
$appPassword = $this->random->generate(72, ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_DIGITS);
$this->tokenProvider->generateToken(
$appPassword,
$userId,
$loginName,
$password,
$data->getClientName(),
IToken::PERMANENT_TOKEN,
IToken::DO_NOT_REMEMBER
);
$data->setLoginName($loginName);
$data->setServer($server);
// Properly encrypt
$data->setAppPassword($this->encryptPassword($appPassword, $data->getPublicKey()));
$this->mapper->update($data);
return true;
}
public function createTokens(string $userAgent): LoginFlowV2Tokens {
$flow = new LoginFlowV2();
$pollToken = $this->random->generate(128, ISecureRandom::CHAR_DIGITS.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER);
$loginToken = $this->random->generate(128, ISecureRandom::CHAR_DIGITS.ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER);
$flow->setPollToken($this->hashToken($pollToken));
$flow->setLoginToken($loginToken);
$flow->setStarted(0);
$flow->setTimestamp($this->time->getTime());
$flow->setClientName($userAgent);
[$publicKey, $privateKey] = $this->getKeyPair();
$privateKey = $this->crypto->encrypt($privateKey, $pollToken);
$flow->setPublicKey($publicKey);
$flow->setPrivateKey($privateKey);
$this->mapper->insert($flow);
return new LoginFlowV2Tokens($loginToken, $pollToken);
}
private function hashToken(string $token): string {
$secret = $this->config->getSystemValue('secret');
return hash('sha512', $token . $secret);
}
private function getKeyPair(): array {
$config = array_merge([
'digest_alg' => 'sha512',
'private_key_bits' => 2048,
], $this->config->getSystemValue('openssl', []));
// Generate new key
$res = openssl_pkey_new($config);
if ($res === false) {
$this->logOpensslError();
throw new \RuntimeException('Could not initialize keys');
}
openssl_pkey_export($res, $privateKey);
// Extract the public key from $res to $pubKey
$publicKey = openssl_pkey_get_details($res);
$publicKey = $publicKey['key'];
return [$publicKey, $privateKey];
}
private function logOpensslError(): void {
$errors = [];
while ($error = openssl_error_string()) {
$errors[] = $error;
}
$this->logger->critical('Something is wrong with your openssl setup: ' . implode(', ', $errors));
}
private function encryptPassword(string $password, string $publicKey): string {
openssl_public_encrypt($password, $encryptedPassword, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
$encryptedPassword = base64_encode($encryptedPassword);
return $encryptedPassword;
}
private function decryptPassword(string $encryptedPassword, string $privateKey): string {
$encryptedPassword = base64_decode($encryptedPassword);
openssl_private_decrypt($encryptedPassword, $password, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
return $password;
}
}

View File

@ -331,12 +331,6 @@ input[type='checkbox'].checkbox--white:checked + label:before {
background-image: url('../img/actions/checkbox-mark-white.svg');
}
/* keep the labels for screen readers but hide them since we use placeholders */
label.infield {
display: none;
}
/* Password strength meter */
.strengthify-wrapper {
display: inline-block;
@ -362,9 +356,6 @@ label.infield {
top: .8em;
float: right;
}
#show, #dbpassword-toggle, #personal-show {
display: none;
}
#show + label, #dbpassword-toggle + label {
right: 21px;
top: 15px !important;
@ -386,6 +377,11 @@ label.infield {
#show + label:before, #dbpassword-toggle + label:before, #personal-show + label:before {
display: none;
}
/* Feedback for keyboard focus and mouse hover */
#show:focus + label, #dbpassword-toggle:focus + label, #personal-show:focus + label,
#show + label:hover, #dbpassword-toggle + label:hover, #personal-show + label:hover {
opacity: 1;
}
#pass2, input[name='personal-password-clone'] {
padding: .6em 2.5em .4em .4em;
width: 8em;
@ -836,6 +832,8 @@ footer .info .entity-name {
display: none;
}
/* keep the labels for screen readers but hide them since we use placeholders */
label.infield,
.hidden-visually {
position: absolute;
left:-10000px;

View File

@ -917,3 +917,14 @@ progress {
animation-duration: .7s;
animation-timing-function: ease-out;
}
// Keep the labels for screen readers but hide them since we use placeholders
// Same as .hidden-visually
label.infield {
position: absolute;
left:-10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}

Some files were not shown because too many files have changed in this diff Show More