Skip to content

Commit

Permalink
#419 Introduce GDPR Privacy Policy link
Browse files Browse the repository at this point in the history
  • Loading branch information
cbellone committed May 4, 2018
1 parent 0970658 commit f1aa626
Show file tree
Hide file tree
Showing 27 changed files with 192 additions and 34 deletions.
4 changes: 3 additions & 1 deletion src/main/java/alfio/controller/form/PaymentForm.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class PaymentForm implements Serializable {
private String hmac;
private Boolean cancelReservation;
private Boolean termAndConditionsAccepted;
private Boolean privacyPolicyAccepted;
private PaymentProxy paymentMethod;
private Boolean expressCheckoutRequested;
private boolean postponeAssignment = false;
Expand Down Expand Up @@ -89,7 +90,8 @@ public void validate(BindingResult bindingResult, TotalPrice reservationCost, Ev
bindingResult.reject(ErrorsCode.STEP_2_MISSING_STRIPE_TOKEN);
}

if(Objects.isNull(termAndConditionsAccepted) || !termAndConditionsAccepted) {
if(Objects.isNull(termAndConditionsAccepted) || !termAndConditionsAccepted
|| (StringUtils.isNotEmpty(event.getPrivacyPolicyUrl()) && (Objects.isNull(privacyPolicyAccepted) || !privacyPolicyAccepted)) ) {
bindingResult.reject(ErrorsCode.STEP_2_TERMS_NOT_ACCEPTED);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import alfio.model.CustomerName;
import alfio.model.Event;
import com.stripe.model.Customer;
import lombok.Data;

import java.util.Locale;
Expand All @@ -31,6 +30,7 @@ public class WaitingQueueSubscriptionForm {
private String email;
private Locale userLanguage;
private boolean termAndConditionsAccepted;
private boolean privacyPolicyAccepted;
private Integer selectedCategory;

public CustomerName toCustomerName(Event event) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/alfio/manager/EventManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ public void updateEventHeader(Event original, EventModification em, String usern
final ZonedDateTime begin = em.getBegin().toZonedDateTime(zoneId);
final ZonedDateTime end = em.getEnd().toZonedDateTime(zoneId);
eventRepository.updateHeader(eventId, em.getDisplayName(), em.getWebsiteUrl(), em.getExternalUrl(), em.getTermsAndConditionsUrl(),
em.getImageUrl(), em.getFileBlobId(), em.getLocation(), em.getLatitude(), em.getLongitude(),
em.getPrivacyPolicyUrl(), em.getImageUrl(), em.getFileBlobId(), em.getLocation(), em.getLatitude(), em.getLongitude(),
begin, end, em.getZoneId(), em.getOrganizationId(), em.getLocales());

createOrUpdateEventDescription(eventId, em);
Expand Down Expand Up @@ -714,7 +714,7 @@ private int insertEvent(EventModification em) {
ZoneId zoneId = ZoneId.of(em.getZoneId());
String currentVersion = flyway.info().current().getVersion().getVersion();
return eventRepository.insert(em.getShortName(), em.getEventType(), em.getDisplayName(), em.getWebsiteUrl(), em.getExternalUrl(), em.isInternal() ? em.getTermsAndConditionsUrl() : "",
em.getImageUrl(), em.getFileBlobId(), em.getLocation(), em.getLatitude(), em.getLongitude(), em.getBegin().toZonedDateTime(zoneId),
em.getPrivacyPolicyUrl(), em.getImageUrl(), em.getFileBlobId(), em.getLocation(), em.getLatitude(), em.getLongitude(), em.getBegin().toZonedDateTime(zoneId),
em.getEnd().toZonedDateTime(zoneId), em.getZoneId(), em.getCurrency(), em.getAvailableSeats(), em.isInternal() && em.isVatIncluded(),
vat, paymentProxies, privateKey, em.getOrganizationId(), em.getLocales(), em.getVatStatus(), em.getPriceInCents(), currentVersion, Event.Status.DRAFT).getKey();
}
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/alfio/model/Event.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public enum EventType {
private final String websiteUrl;
private final String externalUrl;
private final String termsAndConditionsUrl;
private final String privacyPolicyUrl;
private final String imageUrl;
private final String fileBlobId;
private final String location;
Expand Down Expand Up @@ -92,6 +93,7 @@ public Event(@Column("id") int id,
@Column("external_url") String externalUrl,
@Column("file_blob_id") String fileBlobId,
@Column("website_t_c_url") String termsAndConditionsUrl,
@Column("website_p_p_url") String privacyPolicyUrl,
@Column("image_url") String imageUrl,
@Column("currency") String currency,
@Column("vat") BigDecimal vat,
Expand All @@ -109,6 +111,7 @@ public Event(@Column("id") int id,
this.websiteUrl = websiteUrl;
this.externalUrl = externalUrl;
this.termsAndConditionsUrl = termsAndConditionsUrl;
this.privacyPolicyUrl = privacyPolicyUrl;
this.imageUrl = imageUrl;
this.fileBlobId = fileBlobId;

Expand Down Expand Up @@ -245,4 +248,8 @@ public boolean expired() {
public boolean expiredSince(int days) {
return ZonedDateTime.now(getZoneId()).truncatedTo(ChronoUnit.DAYS).minusDays(days).isAfter(getEnd().truncatedTo(ChronoUnit.DAYS));
}

public String getPrivacyPolicyLinkOrNull() {
return StringUtils.trimToNull(privacyPolicyUrl);
}
}
3 changes: 3 additions & 0 deletions src/main/java/alfio/model/modification/EventModification.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class EventModification {
private final String websiteUrl;
private final String externalUrl;
private final String termsAndConditionsUrl;
private final String privacyPolicyUrl;
private final String imageUrl;
private final String fileBlobId;
private final String shortName;
Expand Down Expand Up @@ -71,6 +72,7 @@ public EventModification(@JsonProperty("id") Integer id,
@JsonProperty("websiteUrl") String websiteUrl,
@JsonProperty("external") String externalUrl,
@JsonProperty("termsAndConditionsUrl") String termsAndConditionsUrl,
@JsonProperty("privacyPolicyUrl") String privacyPolicyUrl,
@JsonProperty("imageUrl") String imageUrl,
@JsonProperty("fileBlobId") String fileBlobId,
@JsonProperty("shortName") String shortName,
Expand Down Expand Up @@ -100,6 +102,7 @@ public EventModification(@JsonProperty("id") Integer id,
this.websiteUrl = websiteUrl;
this.externalUrl = externalUrl;
this.termsAndConditionsUrl = termsAndConditionsUrl;
this.privacyPolicyUrl = privacyPolicyUrl;
this.imageUrl = imageUrl;
this.fileBlobId = fileBlobId;
this.shortName = shortName;
Expand Down
51 changes: 39 additions & 12 deletions src/main/java/alfio/repository/EventRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,29 @@ public interface EventRepository {
@Query("select * from event where org_id in (:organizationIds)")
List<Event> findByOrganizationIds(@Bind("organizationIds") Collection<Integer> organizationIds);

@Query("insert into event(short_name, type, display_name, website_url, external_url, website_t_c_url, image_url, file_blob_id, location, latitude, longitude, start_ts, end_ts, time_zone, regular_price_cts, currency, available_seats, vat_included, vat, allowed_payment_proxies, private_key, org_id, locales, vat_status, src_price_cts, version, status) " +
"values(:shortName, :type, :displayName, :websiteUrl, :externalUrl, :termsUrl, :imageUrl, :fileBlobId, :location, :latitude, :longitude, :start_ts, :end_ts, :time_zone, 0, :currency, :available_seats, :vat_included, :vat, :paymentProxies, :privateKey, :organizationId, :locales, :vatStatus, :srcPriceCts, :version, :status)")
@Query("insert into event(short_name, type, display_name, website_url, external_url, website_t_c_url, website_p_p_url, image_url, file_blob_id, location, latitude, longitude, start_ts, end_ts, time_zone, regular_price_cts, currency, available_seats, vat_included, vat, allowed_payment_proxies, private_key, org_id, locales, vat_status, src_price_cts, version, status) " +
"values(:shortName, :type, :displayName, :websiteUrl, :externalUrl, :termsUrl, :privacyUrl, :imageUrl, :fileBlobId, :location, :latitude, :longitude, :start_ts, :end_ts, :time_zone, 0, :currency, :available_seats, :vat_included, :vat, :paymentProxies, :privateKey, :organizationId, :locales, :vatStatus, :srcPriceCts, :version, :status)")
@AutoGeneratedKey("id")
AffectedRowCountAndKey<Integer> insert(@Bind("shortName") String shortName, @Bind("type") Event.EventType type, @Bind("displayName") String displayName,
@Bind("websiteUrl") String websiteUrl, @Bind("externalUrl") String externalUrl, @Bind("termsUrl") String termsUrl, @Bind("imageUrl") String imageUrl, @Bind("fileBlobId") String fileBlobId,
@Bind("location") String location, @Bind("latitude") String latitude, @Bind("longitude") String longitude, @Bind("start_ts") ZonedDateTime begin,
@Bind("end_ts") ZonedDateTime end, @Bind("time_zone") String timeZone, @Bind("currency") String currency,
@Bind("available_seats") int available_seats, @Bind("vat_included") boolean vat_included,
@Bind("vat") BigDecimal vat, @Bind("paymentProxies") String allowedPaymentProxies,
AffectedRowCountAndKey<Integer> insert(@Bind("shortName") String shortName,
@Bind("type") Event.EventType type,
@Bind("displayName") String displayName,
@Bind("websiteUrl") String websiteUrl,
@Bind("externalUrl") String externalUrl,
@Bind("termsUrl") String termsUrl,
@Bind("privacyUrl") String privacyPolicyUrl,
@Bind("imageUrl") String imageUrl,
@Bind("fileBlobId") String fileBlobId,
@Bind("location") String location,
@Bind("latitude") String latitude,
@Bind("longitude") String longitude,
@Bind("start_ts") ZonedDateTime begin,
@Bind("end_ts") ZonedDateTime end,
@Bind("time_zone") String timeZone,
@Bind("currency") String currency,
@Bind("available_seats") int available_seats,
@Bind("vat_included") boolean vat_included,
@Bind("vat") BigDecimal vat,
@Bind("paymentProxies") String allowedPaymentProxies,
@Bind("privateKey") String privateKey,
@Bind("organizationId") int orgId,
@Bind("locales") int locales,
Expand All @@ -72,12 +86,25 @@ AffectedRowCountAndKey<Integer> insert(@Bind("shortName") String shortName, @Bin
@Query("update event set status = :status where id = :id")
int updateEventStatus(@Bind("id") int id, @Bind("status") Event.Status status);

@Query("update event set display_name = :displayName, website_url = :websiteUrl, external_url = :externalUrl, website_t_c_url = :termsUrl, image_url = :imageUrl, file_blob_id = :fileBlobId, " +
@Query("update event set display_name = :displayName, website_url = :websiteUrl, external_url = :externalUrl, website_t_c_url = :termsUrl, website_p_p_url = :privacyUrl, image_url = :imageUrl, file_blob_id = :fileBlobId, " +
"location = :location, latitude = :latitude, longitude = :longitude, start_ts = :start_ts, " +
"end_ts = :end_ts, time_zone = :time_zone, org_id = :organizationId, locales = :locales where id = :id")
int updateHeader(@Bind("id") int id, @Bind("displayName") String displayName, @Bind("websiteUrl") String websiteUrl, @Bind("externalUrl") String externalUrl, @Bind("termsUrl") String termsUrl, @Bind("imageUrl") String imageUrl, @Bind("fileBlobId") String fileBlobId,
@Bind("location") String location, @Bind("latitude") String latitude, @Bind("longitude") String longitude, @Bind("start_ts") ZonedDateTime begin,
@Bind("end_ts") ZonedDateTime end, @Bind("time_zone") String timeZone, @Bind("organizationId") int organizationId, @Bind("locales") int locales);
int updateHeader(@Bind("id") int id,
@Bind("displayName") String displayName,
@Bind("websiteUrl") String websiteUrl,
@Bind("externalUrl") String externalUrl,
@Bind("termsUrl") String termsUrl,
@Bind("privacyUrl") String privacyPolicyUrl,
@Bind("imageUrl") String imageUrl,
@Bind("fileBlobId") String fileBlobId,
@Bind("location") String location,
@Bind("latitude") String latitude,
@Bind("longitude") String longitude,
@Bind("start_ts") ZonedDateTime begin,
@Bind("end_ts") ZonedDateTime end,
@Bind("time_zone") String timeZone,
@Bind("organizationId") int organizationId,
@Bind("locales") int locales);

@Query("update event set currency = :currency, available_seats = :available_seats, vat_included = :vat_included, vat = :vat, allowed_payment_proxies = :paymentProxies, vat_status = :vatStatus, src_price_cts = :srcPriceCts where id = :eventId")
int updatePrices(@Bind("currency") String currency,
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/alfio/util/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,11 @@ public static void validateMaxLength(String value, String fieldName, String erro

public static ValidationResult validateWaitingQueueSubscription(WaitingQueueSubscriptionForm form, Errors errors, Event event) {
if(!form.isTermAndConditionsAccepted()) {
errors.rejectValue("termAndConditionsAccepted", "error.termAndConditionsAccepted");
errors.rejectValue("termAndConditionsAccepted", ErrorsCode.STEP_2_TERMS_NOT_ACCEPTED);
}

if(StringUtils.isNotEmpty(event.getPrivacyPolicyUrl()) && !form.isPrivacyPolicyAccepted()) {
errors.rejectValue("privacyPolicyAccepted", ErrorsCode.STEP_2_TERMS_NOT_ACCEPTED);
}

if(event.mustUseFirstAndLastName()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--
-- This file is part of alf.io.
--
-- alf.io is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- alf.io 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with alf.io. If not, see <http://www.gnu.org/licenses/>.
--

ALTER TABLE EVENT ADD COLUMN website_p_p_url VARCHAR(2048);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--
-- This file is part of alf.io.
--
-- alf.io is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- alf.io 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with alf.io. If not, see <http://www.gnu.org/licenses/>.
--

ALTER TABLE event ADD COLUMN website_p_p_url VARCHAR(2048);
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--
-- This file is part of alf.io.
--
-- alf.io is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- alf.io 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with alf.io. If not, see <http://www.gnu.org/licenses/>.
--

ALTER TABLE EVENT ADD COLUMN website_p_p_url VARCHAR(2048);
5 changes: 4 additions & 1 deletion src/main/resources/alfio/i18n/public.properties
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,7 @@ error.STEP_2_PAYPAL_INSUFFICIENT_FUNDS=Insufficient funds in your PayPal account
error.STEP_2_PAYPAL_EXPIRED_CREDIT_CARD=The card has expired.
error.STEP_2_CAPTCHA_VALIDATION_FAILED=Security check failed. Please try again.
invoice.title=Invoice
invoice.refund=This invoice has been updated after the cancellation of one or more tickets and the refund of {0}.
invoice.refund=This invoice has been updated after the cancellation of one or more tickets and the refund of {0}.
reservation-page.privacy.prefix=I have read and agree to the
reservation-page.privacy.link.text=privacy policy
reservation-page.privacy.suffix=.
3 changes: 3 additions & 0 deletions src/main/resources/alfio/i18n/public_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -341,3 +341,6 @@ error.STEP_2_PAYPAL_INSUFFICIENT_FUNDS=Sie haben nicht gen\u00FCgend Guthaben au
error.STEP_2_CAPTCHA_VALIDATION_FAILED=Sicherheitskontrolle fehlgeschlagen. Bitte versuchen Sie es erneut.
invoice.title=Rechnung
invoice.refund=Diese Rechnung wurde aktualisiert nach eine Storno/R\u00FCckzalung von {0}.
reservation-page.privacy.prefix=Ich habe gelesen und stimme zur
reservation-page.privacy.link.text=Datenschutzerkl\u00E4rung
reservation-page.privacy.suffix=.
5 changes: 4 additions & 1 deletion src/main/resources/alfio/i18n/public_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -350,4 +350,7 @@ error.STEP_2_PAYPAL_INSUFFICIENT_FUNDS=Fond insuffisant sur votre compte PayPal.
error.STEP_2_PAYPAL_EXPIRED_CREDIT_CARD=La carte a expir\u00E9.
error.STEP_2_CAPTCHA_VALIDATION_FAILED=La v\u00E9rification de s\u00E9curti\u00E9 \u00E0 \u00E9chou\u00E9. Essayez \u00E0 nouveau s''il vous plait.
invoice.title=Facture
invoice.refund=Cette facture a \u00E9t\u00E9 modifi\u00E9e suite \u00E0 l'annulation d'un ou de plusieurs billets et le remboursement de {0}.
invoice.refund=Cette facture a \u00E9t\u00E9 modifi\u00E9e suite \u00E0 l'annulation d'un ou de plusieurs billets et le remboursement de {0}.
reservation-page.privacy.prefix=Vous avez lu et acc\u00E9ptez les
reservation-page.privacy.link.text=r\u00E8gles de confidentialit\u00E9
reservation-page.privacy.suffix=.
3 changes: 3 additions & 0 deletions src/main/resources/alfio/i18n/public_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,6 @@ error.STEP_2_PAYPAL_FAILED_TO_CHARGE_CC=Il pagamento \u00E8 stato rifiutato.
error.STEP_2_PAYPAL_INSUFFICIENT_FUNDS=Saldo insufficiente sul conto PayPal.
invoice.title=Fattura
invoice.refund=Questa fattura \u00E8 stata aggiornata dopo la cancellazione di uno o pi\u00F9 biglietti ed il rimborso di {0}.
reservation-page.privacy.prefix=Ho letto ed accetto
reservation-page.privacy.link.text=l''informativa sulla privacy
reservation-page.privacy.suffix=.
3 changes: 3 additions & 0 deletions src/main/resources/alfio/i18n/public_nl.properties
Original file line number Diff line number Diff line change
Expand Up @@ -345,3 +345,6 @@ error.STEP_2_PAYPAL_INSTRUMENT_DECLINED=De geselecteerde methode is geweigerd. C
error.STEP_2_CAPTCHA_VALIDATION_FAILED=Beveiligingscontrole mislukt. Probeer het opnieuw.
invoice.title=Factuur
invoice.refund=Dit factuur is geupdate na de annulering van een of meer tickets en de terugbetaling van {0}.
reservation-page.privacy.prefix=Ik ga akkoord met de
reservation-page.privacy.link.text=Privacybeleid
reservation-page.privacy.suffix=.
9 changes: 9 additions & 0 deletions src/main/webapp/WEB-INF/templates/event/reservation-page.ms
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,15 @@
{{/orderSummary.free}}
<hr/>

{{#event.privacyPolicyLinkOrNull}}
<div class="checkbox wMarginTop wMarginBottom">
<label>
<input type="checkbox" required name="privacyPolicyAccepted" value="true">
{{#i18n}}reservation-page.privacy.prefix{{/i18n}} <a href="{{event.privacyPolicyLinkOrNull}}" target="_blank">{{#i18n}}reservation-page.privacy.link.text{{/i18n}}</a>{{#i18n}}reservation-page.privacy.suffix{{/i18n}}
</label>
</div>
{{/event.privacyPolicyLinkOrNull}}

<div class="checkbox wMarginTop wMarginBottom">
<label>
<input type="checkbox" required name="termAndConditionsAccepted" value="true">
Expand Down
Loading

0 comments on commit f1aa626

Please sign in to comment.