diff --git a/adminstuds.php b/adminstuds.php index 6416bfbb3b956100d80067b335793e7ee6feb8b3..ca920dde83527dfef1c0de4e46f409e098c1a783 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -24,7 +24,7 @@ use Framadate\Services\LogService; use Framadate\Services\MailService; use Framadate\Services\PollService; use Framadate\Services\NotificationService; -use Framadate\Utils; +use Framadate\Security\PasswordHasher; include_once __DIR__ . '/app/inc/init.php'; @@ -71,7 +71,8 @@ if ($poll) { if (isset($_POST['update_poll_info'])) { $updated = false; - $field = $inputService->filterAllowedValues($_POST['update_poll_info'], ['title', 'admin_mail', 'description', 'rules', 'expiration_date', 'name', 'hidden']); + $field = $inputService->filterAllowedValues($_POST['update_poll_info'], ['title', 'admin_mail', 'description', + 'rules', 'expiration_date', 'name', 'hidden', 'removePassword', 'password']); // Update the right poll field if ($field == 'title') { @@ -135,6 +136,24 @@ if (isset($_POST['update_poll_info'])) { $poll->hidden = $hidden; $updated = true; } + } elseif ($field == 'removePassword') { + $removePassword = isset($_POST['removePassword']) ? $inputService->filterBoolean($_POST['removePassword']) : false; + if ($removePassword) { + $poll->results_publicly_visible = false; + $poll->password_hash = null; + $updated = true; + } + } elseif ($field == 'password') { + $password = isset($_POST['password']) ? $_POST['password'] : null; + $resultsPubliclyVisible = isset($_POST['resultsPubliclyVisible']) ? $inputService->filterBoolean($_POST['resultsPubliclyVisible']) : false; + if (!empty($password)) { + $poll->password_hash = PasswordHasher::hash($password); + $updated = true; + } + if ($resultsPubliclyVisible != $poll->results_publicly_visible) { + $poll->results_publicly_visible = $resultsPubliclyVisible; + $updated = true; + } } // Update poll in database diff --git a/app/classes/Framadate/Repositories/PollRepository.php b/app/classes/Framadate/Repositories/PollRepository.php index 0f866cde74d572964c544f3b2c6f7ab07b0ea050..fd62e55fbc3c42c9782e4a3baf4d4e8fccf98084 100644 --- a/app/classes/Framadate/Repositories/PollRepository.php +++ b/app/classes/Framadate/Repositories/PollRepository.php @@ -48,9 +48,9 @@ class PollRepository extends AbstractRepository { } function update($poll) { - $prepared = $this->prepare('UPDATE `' . Utils::table('poll') . '` SET title=?, admin_name=?, admin_mail=?, description=?, end_date=?, active=?, editable=?, hidden=? WHERE id = ?'); + $prepared = $this->prepare('UPDATE `' . Utils::table('poll') . '` SET title=?, admin_name=?, admin_mail=?, description=?, end_date=?, active=?, editable=?, hidden=?, password_hash=?, results_publicly_visible=? WHERE id = ?'); - return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, $poll->editable, $poll->hidden, $poll->id]); + return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, $poll->editable, $poll->hidden, $poll->password_hash, $poll->results_publicly_visible, $poll->id]); } function deleteById($poll_id) { diff --git a/css/style.css b/css/style.css index 16e1865047932505a128b64b9f738256c31540b5..cb2d52481147d3cb8d5863bca754fa3dc62cb512 100644 --- a/css/style.css +++ b/css/style.css @@ -167,6 +167,7 @@ caption { #poll-rules-form .btn-edit, #poll-hidden-form .btn-edit, #expiration-form .btn-edit, +#password-form .btn-edit, #name-form .btn-edit { position:absolute; left:-2000px; @@ -184,6 +185,8 @@ caption { #poll-hidden-form:hover .btn-edit, #expiration-form .btn-edit:focus, #expiration-form:hover .btn-edit, +#password-form .btn-edit:focus, +#password-form:hover .btn-edit, #name-form .btn-edit:focus, #name-form:hover .btn-edit { position:relative !important; @@ -494,4 +497,8 @@ table.results > tbody > tr:hover > td .glyphicon { .password_request { padding-top: 15px; padding-bottom: 15px; +} + +#password-form .btn-cancel { + float: right; } \ No newline at end of file diff --git a/js/core.js b/js/core.js index b05e9622e5b959680c3141389cd1693b19824698..70d9c84b2afd7126b1e1b79c8777c21c54df515f 100644 --- a/js/core.js +++ b/js/core.js @@ -104,6 +104,35 @@ $(document).ready(function() { return false; }); + + $('#password-form .btn-edit').on('click', function() { + $('#password-form p').hide(); + $('#password-form .js-password').removeClass('hidden'); + $('#password').focus(); + return false; + }); + + $('#password-form .btn-cancel').on('click', function() { + $('#password-form p').show(); + $('#password-form .js-password').addClass('hidden'); + $('.js-password .btn-edit').focus(); + return false; + }); + + // Hiding other field when the admin wants to remove the password protection + var removePassword = $('#removePassword'); + removePassword.on('click', function() { + var removeButton = removePassword.siblings('button'); + if (removePassword.is(":checked")) { + $('#password_information').addClass('hidden'); + removeButton.removeClass('hidden'); + } else { + $('#password_information').removeClass('hidden'); + removeButton.addClass('hidden'); + } + removeButton.focus(); + }); + // Horizontal scroll buttons if($('.results').width() > $('.container').width()) { $('.scroll-buttons').removeClass('hidden'); diff --git a/locale/de.json b/locale/de.json index 4528f3435f80f4acbb0ef64ab3d24d1cdadb5490..682f839a664ee075fd0aea232ebca2134cdacd9e 100644 --- a/locale/de.json +++ b/locale/de.json @@ -125,7 +125,11 @@ "Save the new rules": "Neue Regeln speichern", "Cancel the rules edit": "Abbruch, Regeln nicht ändern", "Results are hidden.": "Ergebnisse werden ausgeblendet.", - "Results are visible.": "Ergebnisse sind sichtbar." + "Results are visible.": "Ergebnisse sind sichtbar.", + "Password protected.": "DE_Protégé par mot de passe.", + "Votes protected by password.": "DE_Votes protégés par mot de passe.", + "No password.": "DE_Pas de mot de passe", + "Remove password.": "DE_Supprimer le mot de passe." }, "Poll results": { "Votes of the poll": "Stimmabgaben zur Umfrage", diff --git a/locale/en.json b/locale/en.json index 67af1dd664f840c1178c7a4d4b96e2bc0f419777..90c103b6a090eae2d62b271e26c4e8dbfcc24e50 100644 --- a/locale/en.json +++ b/locale/en.json @@ -125,7 +125,11 @@ "Save the new rules": "Save the new rules", "Cancel the rules edit": "Cancel the rules edit", "Results are hidden.": "Results are hidden.", - "Results are visible.": "Results are visible." + "Results are visible.": "Results are visible.", + "Password protected.": "Password protected.", + "Votes protected by password.": "Votes protected by password.", + "No password.": "No password.", + "Remove password.": "Remove password." }, "Poll results": { "Votes of the poll": "Votes", diff --git a/locale/es.json b/locale/es.json index 5350b3fd76de2673e7de3a539f94ba7ac87a2684..08e06a3895a316328f2dce4ecad48ba0f1ed0b6a 100644 --- a/locale/es.json +++ b/locale/es.json @@ -125,7 +125,11 @@ "Save the new rules": "ES_Enregistrer les nouvelles permissions", "Cancel the rules edit": "ES_Annuler le changement de permissions", "Results are hidden.": "ES_Les résultats sont cachés.", - "Results are visible.": "ES_Les résultats sont visibles." + "Results are visible.": "ES_Les résultats sont visibles.", + "Password protected.": "ES_Protégé par mot de passe.", + "Votes protected by password.": "ES_Votes protégés par mot de passe.", + "No password.": "ES_Pas de mot de passe", + "Remove password.": "ES_Supprimer le mot de passe." }, "Poll results": { "Votes of the poll": "ES_Votes du sondage", diff --git a/locale/fr.json b/locale/fr.json index d76e66e80769bfcce53f5a7f5b703d59c9e81409..e66a8b90c63e77d2b5b73b7eaf5169cf01446d8e 100644 --- a/locale/fr.json +++ b/locale/fr.json @@ -125,7 +125,11 @@ "Save the new rules": "Enregistrer les nouvelles permissions", "Cancel the rules edit": "Annuler le changement de permissions", "Results are hidden.": "Les résultats sont cachés.", - "Results are visible.": "Les résultats sont visibles." + "Results are visible.": "Les résultats sont visibles.", + "Password protected.": "Protégé par mot de passe.", + "Votes protected by password.": "Votes protégés par mot de passe.", + "No password.": "Pas de mot de passe", + "Remove password.": "Supprimer le mot de passe." }, "Poll results": { "Votes of the poll": "Votes du sondage", diff --git a/locale/it.json b/locale/it.json index 81759f0af4be69d76b9df49dce9f93a0f1259673..31db272ff09c70af9c6bb0e69d47fa421934f915 100644 --- a/locale/it.json +++ b/locale/it.json @@ -125,7 +125,11 @@ "Save the new rules": "Salvare i nuovi permessi", "Cancel the rules edit": "Annullare le modifica dei permessi", "Results are hidden.": "I risultati sono nascosti.", - "Results are visible.": "I risultati sono visibili." + "Results are visible.": "I risultati sono visibili.", + "Password protected.": "IT_Protégé par mot de passe.", + "Votes protected by password.": "IT_Votes protégés par mot de passe.", + "No password.": "IT_Pas de mot de passe", + "Remove password.": "IT_Supprimer le mot de passe." }, "Poll results": { "Votes of the poll": "Voti del sondaggio ", diff --git a/tpl/part/poll_info.tpl b/tpl/part/poll_info.tpl index 9c0f7f6f77a70d1d4d4a0324dc3e31abcc9eeb1f..ec77e4ecf59ad404141bc571fa0e432ed16a48e0 100644 --- a/tpl/part/poll_info.tpl +++ b/tpl/part/poll_info.tpl @@ -120,7 +120,42 @@ </div> {if $admin} <div class="row"> - <div class="col-md-4 col-md-offset-4" > + <div class="col-md-4"> + <div id="password-form"> + {if !empty($poll->password_hash) && !$poll->results_publicly_visible} + {$password_text = __('PollInfo', 'Password protected.')} + {elseif !empty($poll->password_hash) && $poll->results_publicly_visible} + {$password_text = __('PollInfo', 'Votes protected by password.')} + {else} + {$password_text = __('PollInfo', 'No password.')} + {/if} + <p class=""><span class="glyphicon glyphicon-lock"> </span> {$password_text}<button class="btn btn-link btn-sm btn-edit" title="{__('PollInfo', 'Edit the poll rules')}"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">{__('Generic', 'Edit')}</span></button></p> + <div class="hidden js-password"> + <button class="btn btn-link btn-cancel" title="{__('PollInfo', 'Cancel the rules edit')}"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">{__('Generic', 'Cancel')}</span></button> + {if !empty($poll->password_hash)} + <div class="input-group"> + <input type="checkbox" id="removePassword" name="removePassword"/> + <label for="removePassword">{__('PollInfo', 'Remove password.')}</label> + <button type="submit" name="update_poll_info" value="removePassword" class="btn btn-success hidden" title="{__('PollInfo', 'Save the new rules')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Remove password.')}</span></button> + </div> + {/if} + <div id="password_information"> + <div class="input-group"> + <input type="checkbox" id="resultsPubliclyVisible" name="resultsPubliclyVisible" {if $poll->results_publicly_visible}checked="checked"{/if}/> + <label for="resultsPubliclyVisible">{__('PollInfo', 'Results are visible.')}</label> + </div> + <div class="input-group"> + <input type="text" class="form-control" id="password" name="password"/> + <span class="input-group-btn"> + <button type="submit" name="update_poll_info" value="password" class="btn btn-success" title="{__('PollInfo', 'Save the new rules')}"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">{__('Generic', 'Save')}</span></button> + </span> + </div> + </div> + </div> + </div> + </div> + + <div class="col-md-4 "> <div id="poll-hidden-form"> {if $poll->hidden} {$hidden_icon = "glyphicon-eye-close"} diff --git a/tpl/part/vote_table_classic.tpl b/tpl/part/vote_table_classic.tpl index e5e5070288e944cb13f7410aa9d10fdf245153c0..660dc105318d570289d7a055869ba710077e0e1c 100644 --- a/tpl/part/vote_table_classic.tpl +++ b/tpl/part/vote_table_classic.tpl @@ -4,7 +4,9 @@ <h3> {__('Poll results', 'Votes of the poll')} {if $hidden}<i>({__('PollInfo', 'Results are hidden.')})</i>{/if} - <a href="" data-toggle="modal" data-target="#hint_modal"><i class="glyphicon glyphicon-info-sign"></i></a> + {if $accessGranted} + <a href="" data-toggle="modal" data-target="#hint_modal"><i class="glyphicon glyphicon-info-sign"></i></a> + {/if} </h3> <div id="tableContainer" class="tableContainer"> diff --git a/tpl/part/vote_table_date.tpl b/tpl/part/vote_table_date.tpl index 8ff1a04512a5fd4ad24cc9508c0adc5e1169f75e..975d42b4a0f90b10400d0db37246effa2b17a172 100644 --- a/tpl/part/vote_table_date.tpl +++ b/tpl/part/vote_table_date.tpl @@ -4,7 +4,9 @@ <h3> {__('Poll results', 'Votes of the poll')} {if $hidden}<i>({__('PollInfo', 'Results are hidden.')})</i>{/if} - <a href="" data-toggle="modal" data-target="#hint_modal"><i class="glyphicon glyphicon-info-sign"></i></a> + {if $accessGranted} + <a href="" data-toggle="modal" data-target="#hint_modal"><i class="glyphicon glyphicon-info-sign"></i></a> + {/if} </h3>