package me.moodcat.backend; import javax.persistence.EntityNotFoundException; import javax.ws.rs.NotAuthorizedException; import lombok.extern.slf4j.Slf4j; import me.moodcat.database.controllers.UserDAO; import me.moodcat.database.entities.User; import me.moodcat.soundcloud.SoundCloudException; import me.moodcat.soundcloud.SoundCloudIdentifier; import me.moodcat.soundcloud.models.MeModel; import com.google.common.base.Preconditions; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.persist.Transactional; /** * The UserBackend allows users to login through SoundCloud. */ @Slf4j public class UserBackend { private final Provider<UserDAO> userDAOProvider; private final SoundCloudIdentifier soundCloudIdentifier; @Inject public UserBackend(final Provider<UserDAO> userDAOProvider, final SoundCloudIdentifier soundCloudIdentifier) { this.userDAOProvider = userDAOProvider; this.soundCloudIdentifier = soundCloudIdentifier; } /** * Login a user using SoundCloud. * * @param token * The SoundCloud token * @return * The User for the token */ public User loginUsingSoundCloud(final String token) { return findOrRegisterUser(token); } private MeModel retrieveMe(final String token) { try { return soundCloudIdentifier.getMe(token); } catch (final SoundCloudException e) { throw new NotAuthorizedException(e.getMessage(), e); } } @Transactional private User findOrRegisterUser(final String token) { Preconditions.checkNotNull(token); final UserDAO userDAO = this.userDAOProvider.get(); try { // Look for user in the caches return userDAO.findByAccessToken(token); } catch (final EntityNotFoundException e) { // User not found in caches log.debug("User token {} not found in caches, querying SoundCloud", token); return createAccessToken(token, userDAO); } } private User createAccessToken(final String token, final UserDAO userDAO) { final MeModel me = retrieveMe(token); final int soundCloudId = me.getId(); try { final User user = userDAO.findBySoundcloudId(soundCloudId); mergePreviousToken(token, userDAO, user); return user; } catch (final EntityNotFoundException e) { User user = createUser(soundCloudId, me); user.setAccessToken(token); return userDAO.persist(user); } } private void mergePreviousToken(final String token, final UserDAO userDAO, final User user) { final String previousToken = user.getAccessToken(); if (!token.equals(previousToken)) { user.setAccessToken(token); userDAO.merge(user); } } private static User createUser(final Integer soundCloudId, final MeModel me) { final User user = new User(); user.setSoundCloudUserId(soundCloudId); user.setAvatarUrl(me.getAvatarUrl()); user.setName(me.getUsername()); return user; } }