/contacts?emailAddressRegEx -> emailAddress with optional '%' as wildcard
This commit is contained in:
parent
3283ed88ba
commit
c1c6f8b92d
@ -40,12 +40,12 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String caption,
|
||||
final String emailAddressRegEx) {
|
||||
final String emailAddress) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
validate("caption, emailAddress").atMaxOne(caption, emailAddressRegEx);
|
||||
final var entities = emailAddressRegEx != null
|
||||
? contactRepo.findContactByEmailAddressRegEx(emailAddressRegEx)
|
||||
validate("caption, emailAddress").atMaxOne(caption, emailAddress);
|
||||
final var entities = emailAddress != null
|
||||
? contactRepo.findContactByEmailAddress(emailAddress)
|
||||
: contactRepo.findContactByOptionalCaptionLike(caption);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeContactResource.class);
|
||||
|
@ -4,8 +4,6 @@ import io.micrometer.core.annotation.Timed;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@ -25,23 +23,13 @@ public interface HsOfficeContactRbacRepository extends Repository<HsOfficeContac
|
||||
|
||||
@Query(value = """
|
||||
select c.* from hs_office.contact_rv c
|
||||
where jsonb_path_exists(c.emailaddresses, cast(:emailAddressExpression as jsonpath))
|
||||
where exists (
|
||||
SELECT 1 FROM jsonb_each_text(c.emailAddresses) AS kv(key, value)
|
||||
WHERE kv.value LIKE :emailAddressRegEx
|
||||
)
|
||||
""", nativeQuery = true)
|
||||
@Timed("app.office.contacts.repo.findContactByEmailAddressImpl.rbac")
|
||||
List<HsOfficeContactRbacEntity> findContactByEmailAddressImpl(final String emailAddressExpression);
|
||||
|
||||
default List<HsOfficeContactRbacEntity> findContactByEmailAddressRegEx(@NotNull final String emailAddress) {
|
||||
return findContactByEmailAddressImpl("$.** ? (@ like_regex \"" + emailRegEx(emailAddress) + "\")");
|
||||
}
|
||||
|
||||
static String emailRegEx(@NotNull String emailAddress) {
|
||||
// TODO.impl: find more secure solution, maybe we substitute a placeholder with the whole expression?
|
||||
if (emailAddress.contains("'") || emailAddress.contains("\"") || emailAddress.endsWith("\\") ) {
|
||||
throw new ValidationException(
|
||||
"emailAddressRegEx contains invalid characters: " + emailAddress);
|
||||
}
|
||||
return emailAddress.replace("%", ".*"); // the JSON-matcher in PostgreSQL needs a wildcard
|
||||
}
|
||||
@Timed("app.office.contacts.repo.findContactByEmailAddress.rbac")
|
||||
List<HsOfficeContactRbacEntity> findContactByEmailAddress(final String emailAddressRegEx);
|
||||
|
||||
@Timed("app.office.contacts.repo.save.rbac")
|
||||
HsOfficeContactRbacEntity save(final HsOfficeContactRbacEntity entity);
|
||||
|
@ -13,13 +13,13 @@ get:
|
||||
schema:
|
||||
type: string
|
||||
description: Beginning of caption to filter the results.
|
||||
- name: emailAddressRegEx
|
||||
- name: emailAddress
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description:
|
||||
Regular-expression for an email-address to filter the results.
|
||||
Email-address to filter the results, use '%' as wildcard.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
@ -21,7 +21,7 @@ get:
|
||||
required: false
|
||||
schema:
|
||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationType'
|
||||
description: Prefix of name properties from holder or contact to filter the results.
|
||||
description: Beginning of name properties from holder or contact to filter the results.
|
||||
- name: mark
|
||||
in: query
|
||||
required: false
|
||||
|
@ -193,7 +193,7 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC
|
||||
context("superuser-alex@hostsharing.net", null);
|
||||
|
||||
// when
|
||||
final var result = contactRepo.findContactByEmailAddressRegEx("@secondcontact.example.com");
|
||||
final var result = contactRepo.findContactByEmailAddress("%@secondcontact.example.com");
|
||||
|
||||
// then
|
||||
exactlyTheseContactsAreReturned(result, "second contact");
|
||||
|
@ -1,29 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.office.contact;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class HsOfficeContactRbacRepositoryUnitTest {
|
||||
|
||||
@Test
|
||||
void rejectsSingleQuoteInEmailAddressRegEx() {
|
||||
final var throwable = catchThrowable( () ->
|
||||
HsOfficeContactRbacRepository.emailRegEx("target@'example.org")
|
||||
);
|
||||
|
||||
assertThat(throwable).isInstanceOf(ValidationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsTrailingBackslashInEmailAddressRegEx() {
|
||||
final var throwable = catchThrowable( () ->
|
||||
HsOfficeContactRbacRepository.emailRegEx("target@example.org\\")
|
||||
);
|
||||
|
||||
assertThat(throwable).isInstanceOf(ValidationException.class);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user