org.jboss.aerogear.unifiedpush.service.impl.AliasServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.aerogear.unifiedpush.service.impl.AliasServiceImpl.java

Source

/**
 * JBoss, Home of Professional Open Source
 * Copyright Red Hat, Inc., and individual contributors.
 *
 * 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 org.jboss.aerogear.unifiedpush.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import javax.inject.Inject;

import org.apache.commons.lang3.StringUtils;
import org.jboss.aerogear.unifiedpush.api.Alias;
import org.jboss.aerogear.unifiedpush.api.PushApplication;
import org.jboss.aerogear.unifiedpush.cassandra.dao.AliasDao;
import org.jboss.aerogear.unifiedpush.cassandra.dao.NullAlias;
import org.jboss.aerogear.unifiedpush.cassandra.dao.model.UserKey;
import org.jboss.aerogear.unifiedpush.service.AliasService;
import org.jboss.aerogear.unifiedpush.service.DocumentService;
import org.jboss.aerogear.unifiedpush.service.PostDelete;
import org.jboss.aerogear.unifiedpush.service.PushApplicationService;
import org.jboss.aerogear.unifiedpush.service.impl.spring.IKeycloakService;
import org.jboss.aerogear.unifiedpush.service.impl.spring.KeycloakServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.datastax.driver.core.utils.UUIDs;

@Service
public class AliasServiceImpl implements AliasService {
    private final Logger logger = LoggerFactory.getLogger(AliasServiceImpl.class);

    @Inject
    private AliasDao aliasDao;
    @Inject
    private IKeycloakService keycloakService;
    @Inject
    private PushApplicationService pushApplicationService;
    @Inject
    private DocumentService documentService;

    public List<Alias> addAll(PushApplication pushApplication, List<Alias> aliases, boolean oauth2) {
        logger.debug("OAuth2 flag is: " + oauth2);
        List<Alias> aliasList = new ArrayList<>();

        // Create keycloak client if missing.
        if (oauth2)
            keycloakService.createClientIfAbsent(pushApplication);

        aliases.forEach(alias -> {
            create(alias);
            aliasList.add(alias);
        });

        return aliasList;
    }

    @Override
    public void updateAliasePassword(String aliasId, String currentPassword, String newPassword) {
        keycloakService.updateUserPassword(aliasId, currentPassword, newPassword);
    }

    @Override
    public List<UserKey> remove(UUID pushApplicationId, String alias) {
        // Remove any aliases related to this alias name
        return remove(pushApplicationId, alias, false);
    }

    @Override
    public List<UserKey> remove(UUID pushApplicationId, UUID userId) {
        return remove(pushApplicationId, userId, false);
    }

    @Override
    public List<UserKey> remove(UUID pushApplicationId, UUID userId, boolean destructive) {
        Alias alias = aliasDao.findOne(pushApplicationId, userId);
        if (alias == null) {
            return Collections.emptyList();
        }
        return this.remove(pushApplicationId,
                StringUtils.isNotEmpty(alias.getEmail()) ? alias.getEmail() : alias.getOther(), destructive);
    }

    private List<UserKey> remove(UUID pushApplicationId, String alias, boolean destructive) {
        // Remove any aliases belong to user_id
        List<UserKey> removed = aliasDao.remove(pushApplicationId, alias);

        if (destructive) {
            // Remove user from keyCloak
            keycloakService.delete(alias);

            documentService.delete(pushApplicationId, find(pushApplicationId.toString(), alias));
        }
        return removed;
    }

    @Override
    public Alias find(String pushApplicationId, String alias) {
        if (StringUtils.isEmpty(alias))
            return NullAlias.getAlias(pushApplicationId);

        return aliasDao.findByAlias(
                StringUtils.isEmpty(pushApplicationId) ? null : UUID.fromString(pushApplicationId), alias);
    }

    @Override
    public Alias find(UUID pushApplicationId, UUID userId) {
        return aliasDao.findOne(pushApplicationId, userId);
    }

    /**
     * Test if user exists / registered to KC.
     *
     * @param alias alias name
     */
    @Override
    public boolean registered(String alias) {
        return keycloakService.exists(alias);
    }

    /**
     * Validate rather an alias is associated to a team/application.
     *
     * @param alias alias name
     * @param fqdn  domain / team name.
     */
    public Associated associated(String alias, String fqdn) {
        PushApplication pushApplication = null;

        // Return application name from fqdn.
        if (StringUtils.isNotEmpty(fqdn)) {
            String applicationName = keycloakService.strip(fqdn);
            pushApplication = pushApplicationService.findByName(applicationName);
        }

        Alias aliasObj = find(pushApplication == null ? null : pushApplication.getPushApplicationID(), alias);

        if (aliasObj != null)
            return new Associated(true, getClientId(aliasObj.getPushApplicationId()), keycloakService.seperator());

        return new Associated(false);
    }

    private Alias exists(UUID pushApplicationUUID, Alias aliasToFind) {
        Alias alias = null;
        if (aliasToFind.getId() != null) {
            alias = aliasDao.findOne(pushApplicationUUID, aliasToFind.getId());

            if (alias != null)
                return alias;
        }

        if (StringUtils.isNotEmpty(aliasToFind.getEmail())) {
            alias = aliasDao.findByAlias(pushApplicationUUID, aliasToFind.getEmail());
            if (alias != null)
                return alias;
        }

        if (StringUtils.isNotEmpty(aliasToFind.getOther())) {
            alias = aliasDao.findByAlias(pushApplicationUUID, aliasToFind.getOther());
            if (alias != null)
                return alias;
        }

        return alias;
    }

    private String getClientId(UUID pushApplicationUUID) {
        PushApplication pushApp = pushApplicationService.findByPushApplicationID(pushApplicationUUID.toString());
        return KeycloakServiceImpl.getClientd(pushApp);
    }

    /*
     * Remove all aliases by application id and invalidates alias cache. destructive
     * - when true also remove KC entities and related documents
     */
    @Override
    @Async
    public void removeAll(PushApplication pushApplication, boolean destructive, PostDelete action) {
        UUID pushApplicationId = UUID.fromString(pushApplication.getPushApplicationID());

        aliasDao.findUserIds(pushApplicationId).map(row -> aliasDao.findOne(pushApplicationId, row.getUUID(0)))
                .filter(alias -> Objects.nonNull(alias)).forEach(alias -> {

                    // If not destructive, only aliases are deleted.
                    if (destructive) {
                        // KC users are registered by email
                        if (StringUtils.isNotEmpty(alias.getEmail()))
                            keycloakService.delete(alias.getEmail());

                        documentService.delete(pushApplicationId, alias);
                    }

                    aliasDao.remove(pushApplicationId, alias.getId());
                });

        if (destructive) {
            keycloakService.removeClient(pushApplication);
        }

        action.after();
    }

    /**
     * Create alias while preserving user uuid.
     */
    @Override
    public void create(Alias alias) {
        // Initialize a new time-based UUID on case one is missing.
        if (alias.getId() == null) {
            // Search if alias is already register for application.
            // If so, use the same userId in-order to keep previous history.
            Alias existingAlias = exists(alias.getPushApplicationId(), alias);

            if (existingAlias != null) {
                // Remove all references to previous alias
                remove(alias.getPushApplicationId(), existingAlias.getId());
                // TODO - if user exists with KC, and primary email changed?
                // Change user alias and enforce registration process

                alias.setId(existingAlias.getId());
            } else {
                alias.setId(UUIDs.timeBased());
            }
        }

        aliasDao.create(alias);
    }

    @Override
    @Async
    public void createAsynchronous(Alias alias) {
        create(alias);
    }

    public class Associated {
        private boolean associated;
        private String client;
        private String seperator;
        private String subdomain;

        public Associated(boolean associated, String client) {
            super();
            this.associated = associated;
            this.client = client;
        }

        public Associated(boolean associated, String client, String seperator) {
            super();
            this.associated = associated;
            this.client = client;
            this.seperator = seperator;
        }

        public Associated(boolean associated) {
            super();
            this.associated = associated;
        }

        public boolean isAssociated() {
            return associated;
        }

        public String getClient() {
            return client;
        }

        public String getSeperator() {
            return seperator;
        }

        public String getSubdomain() {
            return subdomain;
        }

        public void setSubdomain(String subdomain) {
            this.subdomain = subdomain;
        }
    }
}