Skip to content

Commit

Permalink
Static pages / add support for mail links
Browse files Browse the repository at this point in the history
  • Loading branch information
josegar74 committed Jan 15, 2025
1 parent 815191e commit 920d491
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 20 deletions.
43 changes: 43 additions & 0 deletions common/src/main/java/org/fao/geonet/utils/EmailUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//=============================================================================
//=== Copyright (C) 2001-2025 Food and Agriculture Organization of the
//=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
//=== and United Nations Environment Programme (UNEP)
//===
//=== This library is free software; you can redistribute it and/or
//=== modify it under the terms of the GNU Lesser General Public
//=== License as published by the Free Software Foundation; either
//=== version 2.1 of the License, or (at your option) any later version.
//===
//=== This library 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
//=== Lesser General Public License for more details.
//===
//=== You should have received a copy of the GNU Lesser General Public
//=== License along with this library; if not, write to the Free Software
//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//===
//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
//=== Rome - Italy. email: [email protected]
//==============================================================================

package org.fao.geonet.utils;

public class EmailUtil {
private static final String OWASP_EMAIL_REGEX = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
private static final java.util.regex.Pattern OWASP_EMAIL_PATTERN = java.util.regex.Pattern.compile(OWASP_EMAIL_REGEX);

private EmailUtil() {
throw new UnsupportedOperationException();
}

/**
* Checks if a string contains a valid email address format.
*
* @param emailAddress Value to validate.
* @return true if the value contains a valid email address format, otherwise false.
*/
public static boolean isValidEmailAddress(String emailAddress) {
return OWASP_EMAIL_PATTERN.matcher(emailAddress).matches();
}
}
43 changes: 43 additions & 0 deletions common/src/test/java/org/fao/geonet/utils/EmailUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//=============================================================================
//=== Copyright (C) 2001-2025 Food and Agriculture Organization of the
//=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
//=== and United Nations Environment Programme (UNEP)
//===
//=== This library is free software; you can redistribute it and/or
//=== modify it under the terms of the GNU Lesser General Public
//=== License as published by the Free Software Foundation; either
//=== version 2.1 of the License, or (at your option) any later version.
//===
//=== This library 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
//=== Lesser General Public License for more details.
//===
//=== You should have received a copy of the GNU Lesser General Public
//=== License along with this library; if not, write to the Free Software
//=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//===
//=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
//=== Rome - Italy. email: [email protected]
//==============================================================================

package org.fao.geonet.utils;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class EmailUtilTest {
@Test
public void testEmailAddress() {
assertEquals(true, EmailUtil.isValidEmailAddress("[email protected]"));

assertEquals(true, EmailUtil.isValidEmailAddress("[email protected]"));

assertEquals(true, EmailUtil.isValidEmailAddress("[email protected]"));

assertEquals(false, EmailUtil.isValidEmailAddress("test.user"));

assertEquals(false, EmailUtil.isValidEmailAddress("test.user@domain"));
}
}
2 changes: 1 addition & 1 deletion domain/src/main/java/org/fao/geonet/domain/page/Page.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public enum PageStatus {
}

public enum PageFormat {
LINK, HTML, HTMLPAGE, TEXT;
LINK, HTML, HTMLPAGE, TEXT, EMAILLINK;
}

// These are the sections where is shown the link to the Page object
Expand Down
31 changes: 23 additions & 8 deletions services/src/main/java/org/fao/geonet/api/pages/PagesAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.fao.geonet.repository.UserGroupRepository;
import org.fao.geonet.repository.page.PageRepository;
import org.fao.geonet.repository.specification.UserGroupSpecs;
import org.fao.geonet.utils.EmailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
Expand All @@ -58,6 +59,7 @@

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
Expand Down Expand Up @@ -178,7 +180,11 @@ private ResponseEntity<String> createPage(PageProperties pageProperties,
}

if (!StringUtils.isBlank(link)) {
format = Page.PageFormat.LINK;
if (EmailUtil.isValidEmailAddress(link)) {
format = Page.PageFormat.EMAILLINK;
} else {
format = Page.PageFormat.LINK;
}
}

checkMandatoryContent(data, link, content);
Expand Down Expand Up @@ -499,8 +505,8 @@ public Page.PageStatus[] getPageStatus() {
}

private void checkCorrectFormat(final MultipartFile data, final Page.PageFormat format) {
if (Page.PageFormat.LINK.equals(format) && data != null && !data.isEmpty()) {
throw new IllegalArgumentException("Wrong format. Cannot set format to LINK and upload a file.");
if ((Page.PageFormat.LINK.equals(format) || Page.PageFormat.EMAILLINK.equals(format)) && data != null && !data.isEmpty()) {
throw new IllegalArgumentException("Wrong format. Cannot set format to LINK or EMAILLINK and upload a file.");
}
}

Expand Down Expand Up @@ -619,15 +625,24 @@ private void fillContent(final MultipartFile data,
page.setData(content.getBytes());
} else if (page.getData() == null) {
// Check the link, unless it refers to a file uploaded to the page, that contains the original file name.
if (StringUtils.isNotBlank(link) && !UrlUtils.isValidRedirectUrl(link)) {
throw new IllegalArgumentException("The link provided is not valid");
} else {
page.setLink(link);
// The link should be a valid URL or mailto address
if (page.getFormat() == Page.PageFormat.LINK) {
if (StringUtils.isNotBlank(link) && !UrlUtils.isValidRedirectUrl(link)) {
throw new IllegalArgumentException("The link provided is not valid");
} else {
page.setLink(link);
}
} else if (page.getFormat() == Page.PageFormat.EMAILLINK) {
if (StringUtils.isNotBlank(link) && !EmailUtil.isValidEmailAddress(link)) {
throw new IllegalArgumentException("The link provided is not valid");
} else {
page.setLink(link);
}
}
}

}


/**
* Check is the user is in designated group to access the static page when page permission level is set to GROUP
* @param us Current User Session
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2001-2024 Food and Agriculture Organization of the
* Copyright (C) 2001-2025 Food and Agriculture Organization of the
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
* and United Nations Environment Programme (UNEP)
*
Expand Down Expand Up @@ -27,6 +27,7 @@
import org.fao.geonet.api.users.model.UserRegisterDto;
import org.fao.geonet.constants.Params;
import org.fao.geonet.repository.UserRepository;
import org.fao.geonet.utils.EmailUtil;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
Expand All @@ -37,8 +38,6 @@
*
*/
public class UserRegisterDtoValidator implements Validator {
private static final String OWASP_EMAIL_REGEX = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";
private static final java.util.regex.Pattern OWASP_EMAIL_PATTERN = java.util.regex.Pattern.compile(OWASP_EMAIL_REGEX);

@Override
public boolean supports(Class<?> clazz) {
Expand All @@ -55,7 +54,7 @@ public void validate(Object target, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "field.required", Params.EMAIL
+ " is required");

if (StringUtils.hasLength(userRegisterDto.getEmail()) && !OWASP_EMAIL_PATTERN.matcher(userRegisterDto.getEmail()).matches()) {
if (StringUtils.hasLength(userRegisterDto.getEmail()) && !EmailUtil.isValidEmailAddress(userRegisterDto.getEmail())) {
errors.rejectValue("email", "field.notvalid", "Email address is not valid");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,13 @@
$scope.page = $scope.pagesMenu[0];
$scope.isSubmenu = $scope.page.type === "submenu";
$scope.isExternalLink =
$scope.page.format == "LINK" || $scope.page.format == "HTMLPAGE";
$scope.page.format === "LINK" ||
$scope.page.format === "EMAILLINK" ||
$scope.page.format === "HTMLPAGE";

if ($scope.page.format === "EMAILLINK") {
$scope.page.link = "mailto:" + $scope.page.link;
}
}
},
function (response) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
data-ng-repeat="page in page.pages"
class="gn-menuitem-xs"
role="menuitem"
data-ng-init="submenuExternalLink = (page.format == 'LINK' || page.format == 'HTMLPAGE');"
data-ng-init="submenuExternalLink = (page.format == 'LINK' || page.format == 'EMAILLINK' || page.format == 'HTMLPAGE');"
>
<a
data-ng-show="submenuExternalLink"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@

$scope.content = "";
$scope.pageApiLink = gnGlobalSettings.nodeUrl + link + "/content";
if ($scope.staticPageSelected.format !== "LINK") {
if (
$scope.staticPageSelected.format !== "LINK" &&
$scope.staticPageSelected.format !== "EMAILLINK"
) {
$http
.get($scope.action + "/content", { headers: { Accept: "text/html" } })
.then(function (r) {
Expand All @@ -193,6 +196,10 @@
}
};

$scope.isLinkFormat = function (format) {
return format === "LINK" || format === "EMAILLINK";
};

$scope.deleteContent = function () {
$scope.staticPageSelected.link = "";
$scope.staticPageSelected.content = "";
Expand Down
1 change: 1 addition & 0 deletions web-ui/src/main/resources/catalog/locales/en-v4.json
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@
"dataPreview": "Discover data",
"tableOfContents": "Table of Contents",
"staticPageFormat-LINK": "Web link",
"staticPageFormat-EMAILLINK": "Email address link",
"staticPageFormat-HTML": "HTML content displayed embedded in the app",
"staticPageFormat-HTMLPAGE": "HTML content displayed in a new browser tab",
"staticPageFormat-TEXT": "Plain text content",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,23 +178,23 @@
</div>
</div>

<div class="form-group" data-ng-show="staticPageSelected.format === 'LINK'">
<div class="form-group" data-ng-show="isLinkFormat(staticPageSelected.format)">
<label class="control-label col-sm-3" data-translate="">pageLink</label>

<div class="col-sm-9">
<input
type="text"
name="link"
class="form-control"
data-ng-required="staticPageSelected.format === 'LINK'"
data-ng-required="isLinkFormat(staticPageSelected.format)"
data-ng-model="staticPageSelected.link"
/>
</div>
</div>

<!-- Upload panel -->
<div
data-ng-show="staticPageSelected.format !== 'LINK'"
data-ng-show="!isLinkFormat(staticPageSelected.format)"
id="gn-staticpage-uploadfile-row"
class="form-group"
>
Expand Down Expand Up @@ -260,7 +260,7 @@
</div>
</div>

<div class="form-group" data-ng-show="staticPageSelected.format !== 'LINK'">
<div class="form-group" data-ng-show="!isLinkFormat(staticPageSelected.format)">
<label class="control-label col-sm-3" data-translate="">pageContent</label>

<div class="col-sm-9">
Expand Down

0 comments on commit 920d491

Please sign in to comment.