Skip to content
InvitedRegistrationManager.java 6.59 KiB
Newer Older
package it.inaf.ia2.gms.manager;

import it.inaf.ia2.gms.exception.BadRequestException;
import it.inaf.ia2.gms.exception.NotFoundException;
import it.inaf.ia2.gms.exception.UnauthorizedException;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.model.response.InvitedRegistrationItem;
import it.inaf.ia2.gms.persistence.GroupsDAO;
import it.inaf.ia2.gms.persistence.InvitedRegistrationDAO;
import it.inaf.ia2.gms.persistence.LoggingDAO;
import it.inaf.ia2.gms.persistence.MembershipsDAO;
import it.inaf.ia2.gms.persistence.model.GroupEntity;
import it.inaf.ia2.gms.persistence.model.InvitedRegistration;
import it.inaf.ia2.gms.persistence.model.MembershipEntity;
import it.inaf.ia2.gms.service.PermissionsService;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class InvitedRegistrationManager extends UserAwareComponent {

    private static final String INVITED_REGISTRATION = "invited-registration";

    @Autowired
    private GroupsDAO groupsDAO;

    @Autowired
    private MembershipsDAO membershipsDAO;

    @Autowired
    private PermissionsService permissionsService;

    @Autowired
    private PermissionsManager permissionsManager;

    @Autowired
    private InvitedRegistrationDAO invitedRegistrationDAO;

    @Autowired
    private LoggingDAO loggingDAO;

    @Autowired
    private HttpSession httpSession;

    public void addInvitedRegistration(String tokenHash, String email, Map<GroupEntity, Permission> groupsPermissions) {

        Map<String, Permission> groupIdsPermissions = new HashMap<>();
        for (Map.Entry<GroupEntity, Permission> entry : groupsPermissions.entrySet()) {
            GroupEntity group = entry.getKey();
            if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) {
                throw new UnauthorizedException("You don't have the permission to perform invited registrations");
            }
            groupIdsPermissions.put(group.getId(), entry.getValue());
        }

        InvitedRegistration invitedRegistration = new InvitedRegistration()
                .setId(UUID.randomUUID().toString().replaceAll("-", ""))
                .setEmail(email)
                .setTokenHash(tokenHash)
                .setGroupsPermissions(groupIdsPermissions);

        invitedRegistrationDAO.addInvitedRegistration(invitedRegistration);
    }

    public InvitedRegistration getInvitedRegistrationFromToken(String token) {

        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(token.getBytes(StandardCharsets.UTF_8));
            String tokenHash = Base64.getEncoder().encodeToString(hash);

            InvitedRegistration invitedRegistration = invitedRegistrationDAO.getInvitedRegistrationFromToken(tokenHash)
                    .orElseThrow(() -> new NotFoundException("No invited registrations found for this token"));

            httpSession.setAttribute(INVITED_REGISTRATION, invitedRegistration);

            loggingDAO.logAction("Started invited registration for email " + invitedRegistration.getEmail());

            return invitedRegistration;
        } catch (NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }

    public Optional<InvitedRegistration> completeInvitedRegistrationIfNecessary() {

        InvitedRegistration invitedRegistration = (InvitedRegistration) httpSession.getAttribute(INVITED_REGISTRATION);

        if (invitedRegistration != null) {

            for (Map.Entry<String, Permission> entry : invitedRegistration.getGroupsPermissions().entrySet()) {
                String groupId = entry.getKey();
                String userId = getCurrentUserId();

                GroupEntity groupEntity = groupsDAO.findGroupById(groupId).get();

                MembershipEntity membershipEntity = new MembershipEntity();
                membershipEntity.setUserId(userId);
                membershipEntity.setGroupId(groupId);
                membershipsDAO.addMember(membershipEntity);

                permissionsService.addPermission(groupEntity, userId, entry.getValue());
            }

            invitedRegistration.setUserId(getCurrentUserId());
            // FIXME (workaround): separated update for user and done in order to use triggers
            invitedRegistrationDAO.setRegistrationUser(invitedRegistration);
            invitedRegistrationDAO.setRegistrationDone(invitedRegistration);

            httpSession.removeAttribute(INVITED_REGISTRATION);
        }

        return Optional.ofNullable(invitedRegistration);
    }

    public List<InvitedRegistrationItem> getInvitedRegistrationsForGroup(GroupEntity group) {

        if (permissionsManager.getCurrentUserPermission(group) != Permission.ADMIN) {
            return null;
        }

        List<InvitedRegistrationItem> items = new ArrayList<>();

        for (InvitedRegistration reg : invitedRegistrationDAO.getPendingInvitedRegistrationsForGroup(group.getId())) {

            Map<String, Permission> map = reg.getGroupsPermissions();

            if (map != null) {
                for (Permission permission : map.values()) {
                    InvitedRegistrationItem item = new InvitedRegistrationItem()
                            .setId(reg.getId())
                            .setEmail(reg.getEmail())
                            .setPermission(permission)
                            .setCreationTime(reg.getCreationTime());
                    items.add(item);
                }
            }
        }

        return items;
    }

    public void deleteInvitedRegistration(String registrationId, String groupId) {

        GroupEntity group = groupsDAO.findGroupById(groupId)
                .orElseThrow(() -> new BadRequestException("No group found for given id: " + groupId));

        if (permissionsManager.getUserPermission(group, getCurrentUserId()) != Permission.ADMIN) {
            throw new UnauthorizedException("Only administrators can delete invited registrations!");
        }

        invitedRegistrationDAO.deleteInvitedRegistrationRequest(registrationId, groupId);

        loggingDAO.logAction("Deleted invited registration request. "
                + "[request_id=" + registrationId + ", group_id=" + groupId
                + ", group_name=" + group.getName() + "]");
    }