Package org.zanata.action

Source Code of org.zanata.action.UserSettingsAction$CredentialsCreationCallback

/*
* Copyright 2014, Red Hat, Inc. and individual contributors as indicated by the
* @author tags. See the copyright.txt file in the distribution for a full
* listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/
package org.zanata.action;

import static org.jboss.seam.international.StatusMessage.Severity.ERROR;
import static org.jboss.seam.international.StatusMessage.Severity.INFO;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

import javax.faces.context.ExternalContext;
import javax.mail.internet.InternetAddress;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.Size;

import com.googlecode.totallylazy.collections.PersistentMap;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.core.Conversation;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.security.RunAsOperation;
import org.jboss.seam.security.management.IdentityManager;
import org.jboss.seam.security.management.JpaIdentityStore;
import org.zanata.dao.AccountDAO;
import org.zanata.dao.CredentialsDAO;
import org.zanata.dao.PersonDAO;
import org.zanata.email.EmailStrategy;
import org.zanata.i18n.Messages;
import org.zanata.model.HAccount;
import org.zanata.model.HLocale;
import org.zanata.model.HPerson;
import org.zanata.model.security.HCredentials;
import org.zanata.model.security.HOpenIdCredentials;
import org.zanata.security.AuthenticationManager;
import org.zanata.security.openid.FedoraOpenIdProvider;
import org.zanata.security.openid.GoogleOpenIdProvider;
import org.zanata.security.openid.OpenIdAuthCallback;
import org.zanata.security.openid.OpenIdAuthenticationResult;
import org.zanata.security.openid.OpenIdProviderType;
import org.zanata.security.openid.YahooOpenIdProvider;
import org.zanata.service.EmailService;
import org.zanata.service.LanguageTeamService;
import org.zanata.service.impl.EmailChangeService;

import com.google.common.collect.Lists;
import org.zanata.util.ComparatorUtil;
import org.zanata.util.ServiceLocator;

/**
* This is an action class that should eventually replace the
* {@link org.zanata.action.ProfileAction} class as the UI controller for user
* settings.
*
* @author Carlos Munoz <a
*         href="mailto:camunoz@redhat.com">camunoz@redhat.com</a>
* @see {@link org.zanata.action.ProfileAction}
*/
@Name("userSettingsAction")
@Scope(ScopeType.PAGE)
@Slf4j
public class UserSettingsAction {

    @In
    private EmailService emailServiceImpl;
    @In
    private EmailChangeService emailChangeService;

    @In
    private PersonDAO personDAO;

    @In
    private AccountDAO accountDAO;

    @In
    private IdentityManager identityManager;

    @In
    private AuthenticationManager authenticationManager;

    @In
    private LanguageTeamService languageTeamServiceImpl;

    @In
    private Messages msgs;

    @In(value = JpaIdentityStore.AUTHENTICATED_USER)
    HAccount authenticatedAccount;

    @Getter
    @Setter
    @Email
    @NotEmpty
    private String emailAddress;

    @Getter
    @Setter
    @NotEmpty
    @Size(min = 6, max = 20)
    private String newPassword;

    @Getter
    @Setter
    @NotEmpty
    private String oldPassword;

    @Getter
    @Setter
    private String openId;

    @Getter
    @Setter
    @NotEmpty
    @Size(min = 2, max = 80)
    private String accountName;

    @Create
    public void onCreate() {
        HPerson person =
                personDAO.findById(authenticatedAccount.getPerson().getId());
        emailAddress = person.getEmail();
        accountName = person.getName();
    }

    public void updateEmail() {
        if(!isEmailAddressValid(emailAddress)) {
            FacesMessages.instance().addToControl("email",
                    "This email address is already taken");
            return;
        }

        HPerson person =
                personDAO.findById(authenticatedAccount.getPerson().getId(),
                        true);
        if (!authenticatedAccount.getPerson().getEmail().equals(emailAddress)) {
            String activationKey =
                    emailChangeService.generateActivationKey(person,
                            emailAddress);
            // TODO create a separate field for newEmail, perhaps in this class
            String message =
                    emailServiceImpl.sendEmailValidationEmail(this.accountName,
                            this.emailAddress, activationKey);
            FacesMessages.instance().add(message);
        }
    }

    protected boolean isEmailAddressValid(String email) {
        HPerson person = personDAO.findByEmail(email);
        return person == null
                || person.getAccount().equals(authenticatedAccount);
    }

    public void changePassword() {
        if (isPasswordSet()
                && !identityManager.authenticate(
                authenticatedAccount.getUsername(), oldPassword)) {
            FacesMessages.instance().addToControl("oldPassword",
                    "Old password is incorrect, please check and try again.");
            return;
        }

        new RunAsOperation() {
            public void execute() {
                identityManager.changePassword(
                        authenticatedAccount.getUsername(), newPassword);
            }
        }.addRole("admin").run();

        FacesMessages.instance().add(
                "Your password has been successfully changed.");
    }

    public boolean isPasswordSet() {
        return authenticatedAccount.getPasswordHash() != null;
    }

    public List<HCredentials> getUserCredentials() {
        HAccount account = accountDAO.findById(authenticatedAccount.getId());
        return Lists.newArrayList(account.getCredentials());
    }

    public String getAccountUsername() {
        return authenticatedAccount.getUsername();
    }

    /**
     * Valid Types:
     * google, yahoo, fedora, openid for everything else
     */
    public String getCredentialsType(HCredentials credentials) {
        if( new GoogleOpenIdProvider().accepts(credentials.getUser()) ) {
            return "google";
        }
        else if( new FedoraOpenIdProvider().accepts(credentials.getUser()) ) {
            return "fedora";
        }
        else if( new YahooOpenIdProvider().accepts(credentials.getUser()) ) {
            return "yahoo";
        }
        else {
            return "openid";
        }
    }

    public String getCredentialsTypeDisplayName(String type) {
        if(type.equals("google"))
            return "Google";
        else if(type.equals("fedora"))
            return "Fedora";
        if(type.equals("yahoo"))
            return "Yahoo";
        if(type.equals("openid"))
            return "Open Id";
        else
            return "Unknown";
    }

    public void remove(HCredentials toRemove) {
        HAccount account =
                accountDAO.findById(authenticatedAccount.getId(), false);
        account.getCredentials().remove(toRemove);
        //userCredentials = new ArrayList<HCredentials>(account.getCredentials()); // Reload
        // the
        // credentials
        accountDAO.makePersistent(account);
        accountDAO.flush();
    }

    public void verifyCredentials(String providerTypeStr) {
        OpenIdProviderType providerType =
                OpenIdProviderType.valueOf(providerTypeStr);
        HOpenIdCredentials newCreds = new HOpenIdCredentials();
        newCreds.setAccount(authenticatedAccount);
        if( providerType == OpenIdProviderType.Generic ) {
            authenticationManager.openIdAuthenticate(openId, providerType,
                    new CredentialsCreationCallback(newCreds));
        }
        else {
            authenticationManager.openIdAuthenticate(providerType,
                    new CredentialsCreationCallback(newCreds));
        }
    }

    public boolean isApiKeyGenerated() {
        HAccount account =
                accountDAO.findById(authenticatedAccount.getId());

        return account.getApiKey() != null;
    }

    public String getAccountApiKey() {
        HAccount account =
                accountDAO.findById(authenticatedAccount.getId());
        return account.getApiKey();
    }

    public String getUrlKeyLabel() {
        return getKeyPrefix() + ".url=";
    }

    public String getApiKeyLabel() {
        return getKeyPrefix() + ".key=";
    }

    public String getUsernameKeyLabel() {
        return getKeyPrefix() + ".username=";
    }

    /*
     * Replace server name that contains '.' to '_'
     */
    private String getKeyPrefix() {
        ExternalContext context = javax.faces.context.FacesContext
                .getCurrentInstance().getExternalContext();
        HttpServletRequest request = (HttpServletRequest) context
                .getRequest();
        String serverName = request.getServerName();
        if (serverName == null) {
            return "";
        }
        return serverName.replace(".", "_");
    }

    public void regenerateApiKey() {
        HAccount account =
                accountDAO.findById(authenticatedAccount.getId());

        accountDAO.createApiKey(account);
        accountDAO.makePersistent(account);
        log.info("Reset API key for {}", account.getUsername());
    }

    public void updateProfile() {
        HPerson person =
                personDAO.findById(authenticatedAccount.getPerson().getId());
        person.setName( accountName );
        // Update the injected object as well.
        // TODO When more fields are added, we'll need a better solution
        authenticatedAccount.getPerson().setName( accountName );
        personDAO.makePersistent(person);
        FacesMessages.instance().add(
                msgs.get("jsf.dashboard.settings.profileUpdated.message"));
    }

    // TODO Cache this
    public List<HLocale> getUserLanguageTeams() {
        List<HLocale> localeList =
                languageTeamServiceImpl.getLanguageMemberships(
                    authenticatedAccount.getUsername());
        Collections.sort(localeList, ComparatorUtil.LOCALE_COMPARATOR);
        return localeList;
    }

    @Transactional
    public void leaveLanguageTeam(String localeId) {
        languageTeamServiceImpl.leaveLanguageTeam(localeId,
                authenticatedAccount.getPerson().getId());
        FacesMessages.instance().add(
                msgs.format("jsf.dashboard.settings.leaveLangTeam.message",
                        localeId));
    }

    /**
     * Callback for credential creation.
     */
    private static class CredentialsCreationCallback implements
            OpenIdAuthCallback, Serializable {
        private static final long serialVersionUID = 1L;
        private HCredentials newCredentials;

        private CredentialsCreationCallback(HCredentials newCredentials) {
            this.newCredentials = newCredentials;
        }

        @Override
        public void afterOpenIdAuth(OpenIdAuthenticationResult result) {
            // Save the credentials after a successful authentication
            if (result.isAuthenticated()) {
                this.newCredentials.setUser(result.getAuthenticatedId());
                this.newCredentials.setEmail(result.getEmail());
                // NB: Seam component injection won't work on callbacks
                EntityManager em =
                        ServiceLocator.instance().getEntityManager();
                CredentialsDAO credentialsDAO =
                        ServiceLocator.instance().getInstance(
                                CredentialsDAO.class);

                Conversation.instance().begin(true, false); // (To retain
                // messages)
                FacesMessages.instance().clear();

                if (credentialsDAO.findByUser(result.getAuthenticatedId()) != null) {
                    FacesMessages.instance().add(ERROR,
                            "jsf.identities.invalid.Duplicate", null,
                            "Duplicate identity",
                            "This Identity is already in use.");
                } else {
                    em.persist(this.newCredentials);
                    FacesMessages
                            .instance()
                            .add(INFO, "jsf.identities.IdentityAdded", null,
                                    "Identity Added",
                                    "Your new identity has been added to this account.");
                }
            }
        }

        @Override
        public String getRedirectToUrl() {
            return "/dashboard/settings?cid="
                    + Conversation.instance().getId(); // keep the same
            // conversation
        }
    }

}
TOP

Related Classes of org.zanata.action.UserSettingsAction$CredentialsCreationCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.