/* * Copyright 2015-2016 OpenCB * * 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.opencb.opencga.catalog.auth.authentication; import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.commons.datastore.core.QueryResult; import org.opencb.commons.utils.StringUtils; import org.opencb.opencga.catalog.config.Configuration; import org.opencb.opencga.catalog.db.DBAdaptorFactory; import org.opencb.opencga.catalog.db.api.MetaDBAdaptor; import org.opencb.opencga.catalog.db.api.UserDBAdaptor; import org.opencb.opencga.catalog.exceptions.CatalogDBException; import org.opencb.opencga.catalog.exceptions.CatalogException; import org.opencb.opencga.catalog.models.Session; import org.opencb.opencga.catalog.models.User; import org.opencb.opencga.catalog.utils.ParamUtils; import org.opencb.opencga.core.common.MailUtils; import java.security.NoSuchAlgorithmException; /** * @author Jacobo Coll <jacobo167@gmail.com> */ public class CatalogAuthenticationManager implements AuthenticationManager { protected final UserDBAdaptor userDBAdaptor; protected final MetaDBAdaptor metaDBAdaptor; protected final Configuration configuration; public CatalogAuthenticationManager(DBAdaptorFactory dbAdaptorFactory, Configuration configuration) { this.userDBAdaptor = dbAdaptorFactory.getCatalogUserDBAdaptor(); this.metaDBAdaptor = dbAdaptorFactory.getCatalogMetaDBAdaptor(); this.configuration = configuration; } public static String cypherPassword(String password) throws CatalogException { try { return StringUtils.sha1(password); } catch (NoSuchAlgorithmException e) { throw new CatalogDBException("Could not encode password", e); } } @Override public boolean authenticate(String userId, String password, boolean throwException) throws CatalogException { String cypherPassword = (password.length() != 40) ? cypherPassword(password) : password; String storedPassword; boolean validSessionId = false; if (userId.equals("admin")) { storedPassword = metaDBAdaptor.getAdminPassword(); validSessionId = metaDBAdaptor.checkValidAdminSession(password); } else { storedPassword = userDBAdaptor.get(userId, new QueryOptions(QueryOptions.INCLUDE, "password"), null).first().getPassword(); QueryResult<Session> session = userDBAdaptor.getSession(userId, password); if (session.getNumResults() > 0) { validSessionId = true; } } if (storedPassword.equals(cypherPassword) || validSessionId) { return true; } else { if (throwException) { throw new CatalogException("Bad user or password"); } else { return false; } } } @Override public String getUserId(String token) throws CatalogException { if (token == null || token.isEmpty() || token.equalsIgnoreCase("null")) { return "anonymous"; } // Check admin if (token.length() == 40) { // TODO: Replace the dbAdaptor method to return the whole session structure to check if it has expired. if (metaDBAdaptor.checkValidAdminSession(token)) { return "admin"; } throw new CatalogException("The session id does not correspond to any user."); } // Check user if (token.length() == 20) { // TODO: Replace the dbAdaptor method to return the whole session structure to check if it has expired. String userId = userDBAdaptor.getUserIdBySessionId(token); if (userId.isEmpty()) { throw new CatalogException("The session id does not correspond to any user."); } return userId; } throw new CatalogException("The session id introduced is not correct."); } @Override public void changePassword(String userId, String oldPassword, String newPassword) throws CatalogException { String oldCryptPass = (oldPassword.length() != 40) ? cypherPassword(oldPassword) : oldPassword; String newCryptPass = (newPassword.length() != 40) ? cypherPassword(newPassword) : newPassword; userDBAdaptor.changePassword(userId, oldCryptPass, newCryptPass); } @Override public void newPassword(String userId, String newPassword) throws CatalogException { String newCryptPass = (newPassword.length() != 40) ? cypherPassword(newPassword) : newPassword; userDBAdaptor.changePassword(userId, "", newCryptPass); } @Override public QueryResult resetPassword(String userId) throws CatalogException { ParamUtils.checkParameter(userId, "userId"); userDBAdaptor.updateUserLastModified(userId); String newPassword = StringUtils.randomString(6); String newCryptPass = cypherPassword(newPassword); QueryResult<User> user = userDBAdaptor.get(userId, new QueryOptions(QueryOptions.INCLUDE, UserDBAdaptor.QueryParams.EMAIL.key()), ""); if (user == null && user.getNumResults() != 1) { throw new CatalogException("Could not retrieve the user e-mail."); } String email = user.first().getEmail(); QueryResult qr = userDBAdaptor.resetPassword(userId, email, newCryptPass); /* String mailUser = catalogProperties.getProperty(CatalogManager.CATALOG_MAIL_USER); String mailPassword = catalogProperties.getProperty(CatalogManager.CATALOG_MAIL_PASSWORD); String mailHost = catalogProperties.getProperty(CatalogManager.CATALOG_MAIL_HOST); String mailPort = catalogProperties.getProperty(CatalogManager.CATALOG_MAIL_PORT); */ String mailUser = configuration.getEmail().getFrom(); String mailPassword = configuration.getEmail().getPassword(); String mailHost = configuration.getEmail().getHost(); String mailPort = configuration.getEmail().getPort(); MailUtils.sendResetPasswordMail(email, newPassword, mailUser, mailPassword, mailHost, mailPort); return qr; } }