io.gravitee.rest.api.service.impl.InvitationServiceImpl Maven / Gradle / Ivy
/**
* Copyright (C) 2015 The Gravitee team (http://gravitee.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.gravitee.rest.api.service.impl;
import static io.gravitee.rest.api.model.permissions.RolePermissionAction.*;
import static io.gravitee.rest.api.service.common.JWTHelper.ACTION.GROUP_INVITATION;
import static io.gravitee.rest.api.service.notification.NotificationParamsBuilder.REGISTRATION_PATH;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;
import io.gravitee.common.data.domain.Page;
import io.gravitee.repository.exceptions.TechnicalException;
import io.gravitee.repository.management.api.InvitationRepository;
import io.gravitee.repository.management.model.Invitation;
import io.gravitee.rest.api.model.*;
import io.gravitee.rest.api.model.common.PageableImpl;
import io.gravitee.rest.api.model.permissions.RolePermission;
import io.gravitee.rest.api.model.permissions.RoleScope;
import io.gravitee.rest.api.service.*;
import io.gravitee.rest.api.service.MembershipService.MembershipReference;
import io.gravitee.rest.api.service.builder.EmailNotificationBuilder;
import io.gravitee.rest.api.service.common.GraviteeContext;
import io.gravitee.rest.api.service.common.RandomString;
import io.gravitee.rest.api.service.exceptions.InvitationEmailAlreadyExistsException;
import io.gravitee.rest.api.service.exceptions.InvitationNotFoundException;
import io.gravitee.rest.api.service.exceptions.MemberEmailAlreadyExistsException;
import io.gravitee.rest.api.service.exceptions.TechnicalManagementException;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author Azize ELAMRANI (azize at graviteesource.com)
* @author GraviteeSource Team
*/
@Component
public class InvitationServiceImpl extends TransactionalService implements InvitationService {
private final Logger LOGGER = LoggerFactory.getLogger(InvitationServiceImpl.class);
@Autowired
private InvitationRepository invitationRepository;
@Autowired
private EmailService emailService;
@Autowired
private UserService userService;
@Autowired
private MembershipService membershipService;
@Autowired
private RoleService roleService;
@Autowired
private GroupService groupService;
@Autowired
PermissionService permissionService;
@Override
public InvitationEntity create(final NewInvitationEntity invitation) {
final List invitations = findByReference(invitation.getReferenceType(), invitation.getReferenceId());
if (invitations.stream().map(InvitationEntity::getEmail).anyMatch(invitation.getEmail()::equals)) {
throw new InvitationEmailAlreadyExistsException(invitation.getEmail());
}
try {
// First check if user exists
final Optional existingUser = userService.findByEmail(invitation.getEmail());
if (existingUser.isPresent()) {
final UserEntity user = existingUser.get();
Set groupUsers = membershipService
.getMembershipsByReference(MembershipReferenceType.GROUP, invitation.getReferenceId())
.stream()
.map(MembershipEntity::getMemberId)
.collect(Collectors.toSet());
final GroupEntity group = groupService.findById(invitation.getReferenceId());
if (groupUsers.contains(user.getId())) {
throw new MemberEmailAlreadyExistsException(invitation.getEmail());
}
// override permission if not allowed
final boolean hasPermission = permissionService.hasPermission(
RolePermission.ENVIRONMENT_GROUP,
GraviteeContext.getCurrentEnvironment(),
CREATE,
UPDATE,
DELETE
);
if (!hasPermission && group.isLockApiRole()) {
invitation.setApiRole(null);
}
if (!hasPermission && group.isLockApplicationRole()) {
invitation.setApplicationRole(null);
}
addMember(
invitation.getReferenceType().name(),
invitation.getReferenceId(),
user.getId(),
invitation.getApiRole(),
invitation.getApplicationRole()
);
return null;
} else {
sendGroupInvitationEmail(invitation);
final Invitation createdInvitation = invitationRepository.create(convert(invitation));
return convert(createdInvitation);
}
} catch (TechnicalException ex) {
final String message = "An error occurs while trying to create invitation for email " + invitation.getEmail();
LOGGER.error(message, ex);
throw new TechnicalManagementException(message, ex);
}
}
@Override
public InvitationEntity update(final UpdateInvitationEntity invitation) {
try {
final Optional invitationOptional = invitationRepository.findById(invitation.getId());
if (invitationOptional.isPresent()) {
final Invitation invitationToUpdate = invitationOptional.get();
if (!invitationToUpdate.getReferenceId().equals(invitation.getReferenceId())) {
throw new InvitationNotFoundException(invitation.getId());
}
invitationToUpdate.setApiRole(invitation.getApiRole());
invitationToUpdate.setApplicationRole(invitation.getApplicationRole());
invitationToUpdate.setUpdatedAt(new Date());
return convert(invitationRepository.update(invitationToUpdate));
} else {
throw new InvitationNotFoundException(invitation.getId());
}
} catch (TechnicalException ex) {
final String message = "An error occurs while trying to update invitation with email " + invitation.getEmail();
LOGGER.error(message, ex);
throw new TechnicalManagementException(message, ex);
}
}
@Override
public void addMember(
final String referenceType,
final String referenceId,
final String userId,
final String apiRole,
final String applicationRole
) {
addOrUpdateMemberByScope(referenceType, referenceId, userId, RoleScope.API, apiRole);
addOrUpdateMemberByScope(referenceType, referenceId, userId, RoleScope.APPLICATION, applicationRole);
addOrUpdateMemberByScope(referenceType, referenceId, userId, RoleScope.GROUP, null);
}
private void addOrUpdateMemberByScope(
final String referenceType,
final String referenceId,
final String userId,
final RoleScope roleScope,
final String defaultRole
) {
String defaultRoleName = null;
if (defaultRole == null) {
final List defaultRoles = roleService.findDefaultRoleByScopes(roleScope);
if (defaultRoles != null && !defaultRoles.isEmpty()) {
defaultRoleName = defaultRoles.get(0).getName();
}
} else {
defaultRoleName = defaultRole;
}
if (defaultRoleName != null) {
membershipService.addRoleToMemberOnReference(
new MembershipReference(MembershipReferenceType.valueOf(referenceType), referenceId),
new MembershipService.MembershipMember(userId, null, MembershipMemberType.USER),
new MembershipService.MembershipRole(roleScope, defaultRoleName)
);
}
}
private void sendGroupInvitationEmail(NewInvitationEntity invitation) {
final UserEntity userEntity = new UserEntity();
userEntity.setEmail(invitation.getEmail());
final GroupEntity group = groupService.findById(invitation.getReferenceId());
emailService.sendEmailNotification(
new EmailNotificationBuilder()
.to(invitation.getEmail())
.template(EmailNotificationBuilder.EmailTemplate.TEMPLATES_FOR_ACTION_USER_GROUP_INVITATION)
.params(userService.getTokenRegistrationParams(userEntity, REGISTRATION_PATH, GROUP_INVITATION))
.param("group", group)
.build()
);
}
@Override
public List findAll() {
try {
final Set invitations = invitationRepository.findAll();
return invitations.stream().map(this::convert).collect(toList());
} catch (TechnicalException ex) {
final String message = "An error occurs while trying to list all invitations";
LOGGER.error(message, ex);
throw new TechnicalManagementException(message, ex);
}
}
@Override
public List findByReference(final InvitationReferenceType referenceType, final String referenceId) {
try {
final List invitations = invitationRepository.findByReference(referenceType.name(), referenceId);
return invitations.stream().map(this::convert).sorted(comparing(InvitationEntity::getEmail)).collect(toList());
} catch (TechnicalException ex) {
final String message = "An error occurs while trying to list invitations by reference " + referenceType + '/' + referenceId;
LOGGER.error(message, ex);
throw new TechnicalManagementException(message, ex);
}
}
@Override
public void delete(final String invitationId, final String referenceId) {
try {
final Optional optionalInvitation = invitationRepository.findById(invitationId);
if (!optionalInvitation.isPresent() || !optionalInvitation.get().getReferenceId().equals(referenceId)) {
throw new InvitationNotFoundException(invitationId);
}
invitationRepository.delete(invitationId);
} catch (TechnicalException te) {
final String msg = "An error occurs while trying to delete the invitation " + invitationId;
LOGGER.error(msg, te);
throw new TechnicalManagementException(msg, te);
}
}
private Invitation convert(final NewInvitationEntity invitationEntity) {
final Invitation invitation = new Invitation();
invitation.setId(RandomString.generate());
invitation.setReferenceId(invitationEntity.getReferenceId());
invitation.setReferenceType(invitationEntity.getReferenceType().name());
invitation.setApiRole(invitationEntity.getApiRole());
invitation.setApplicationRole(invitationEntity.getApplicationRole());
invitation.setEmail(invitationEntity.getEmail());
final Date now = new Date();
invitation.setCreatedAt(now);
return invitation;
}
private InvitationEntity convert(final Invitation invitation) {
final InvitationEntity invitationEntity = new InvitationEntity();
invitationEntity.setId(invitation.getId());
invitationEntity.setReferenceId(invitation.getReferenceId());
invitationEntity.setReferenceType(InvitationReferenceType.valueOf(invitation.getReferenceType()));
invitationEntity.setApiRole(invitation.getApiRole());
invitationEntity.setApplicationRole(invitation.getApplicationRole());
invitationEntity.setEmail(invitation.getEmail());
invitationEntity.setCreatedAt(invitation.getCreatedAt());
return invitationEntity;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy