major classes refactoring

This commit is contained in:
Athou
2013-04-11 20:49:08 +02:00
parent 54ebf7b9db
commit 5b5ad242e0
31 changed files with 380 additions and 297 deletions

View File

@@ -0,0 +1,75 @@
package com.commafeed.backend.services;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import com.commafeed.backend.dao.FeedCategoryDAO;
import com.commafeed.backend.dao.FeedDAO;
import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.User;
import com.google.api.client.util.Lists;
@Stateless
public class FeedSubscriptionService {
@Inject
FeedCategoryDAO feedCategoryDAO;
@Inject
FeedDAO feedDAO;
@Inject
FeedEntryDAO feedEntryDAO;
@Inject
FeedEntryStatusDAO feedEntryStatusDAO;
@Inject
FeedSubscriptionDAO feedSubscriptionDAO;
public void subscribe(User user, String url, String title,
FeedCategory category) {
Feed feed = feedDAO.findByUrl(url);
if (feed == null) {
feed = new Feed();
feed.setUrl(url);
feedDAO.save(feed);
}
FeedSubscription sub = feedSubscriptionDAO.findByFeed(user, feed);
boolean newSubscription = false;
if (sub == null) {
sub = new FeedSubscription();
sub.setFeed(feed);
sub.setUser(user);
newSubscription = true;
}
sub.setCategory(category);
sub.setTitle(title);
feedSubscriptionDAO.saveOrUpdate(sub);
if (newSubscription) {
List<FeedEntryStatus> statuses = Lists.newArrayList();
List<FeedEntry> allEntries = feedEntryDAO.findByFeed(feed, 0,
10);
for (FeedEntry entry : allEntries) {
FeedEntryStatus status = new FeedEntryStatus();
status.setEntry(entry);
status.setRead(true);
status.setSubscription(sub);
statuses.add(status);
}
feedEntryStatusDAO.save(statuses);
}
}
}

View File

@@ -0,0 +1,89 @@
package com.commafeed.backend.services;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import com.commafeed.backend.dao.FeedDAO;
import com.commafeed.backend.dao.FeedEntryDAO;
import com.commafeed.backend.dao.FeedEntryStatusDAO;
import com.commafeed.backend.dao.FeedSubscriptionDAO;
import com.commafeed.backend.model.Feed;
import com.commafeed.backend.model.FeedEntry;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.google.common.collect.Lists;
@Stateless
public class FeedUpdateService {
@Inject
FeedDAO feedDAO;
@Inject
FeedSubscriptionDAO feedSubscriptionDAO;
@Inject
FeedEntryDAO feedEntryDAO;
@Inject
FeedEntryStatusDAO feedEntryStatusDAO;
public void updateEntries(String url, Collection<FeedEntry> entries) {
Feed feed = feedDAO.findByUrl(url);
List<String> guids = Lists.newArrayList();
for (FeedEntry entry : entries) {
guids.add(entry.getGuid());
}
List<FeedEntry> existingEntries = guids.isEmpty() ? new ArrayList<FeedEntry>()
: feedEntryDAO.findByGuids(guids);
for (FeedEntry entry : entries) {
FeedEntry foundEntry = null;
for (FeedEntry existingEntry : existingEntries) {
if (StringUtils
.equals(entry.getGuid(), existingEntry.getGuid())) {
foundEntry = existingEntry;
break;
}
}
if (foundEntry == null) {
entry.setInserted(Calendar.getInstance().getTime());
addFeedToEntry(entry, feed);
} else {
boolean foundFeed = false;
for (Feed existingFeed : foundEntry.getFeeds()) {
if (ObjectUtils.equals(existingFeed.getId(), feed.getId())) {
foundFeed = true;
break;
}
}
if (!foundFeed) {
addFeedToEntry(foundEntry, feed);
}
}
}
}
private void addFeedToEntry(FeedEntry entry, Feed feed) {
entry.getFeeds().add(feed);
feedEntryDAO.saveOrUpdate(entry);
List<FeedSubscription> subscriptions = feedSubscriptionDAO
.findByFeed(feed);
for (FeedSubscription sub : subscriptions) {
FeedEntryStatus status = new FeedEntryStatus();
status.setEntry(entry);
status.setSubscription(sub);
feedEntryStatusDAO.save(status);
}
}
}

View File

@@ -0,0 +1,89 @@
package com.commafeed.backend.services;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import java.util.Arrays;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.ejb.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.commafeed.backend.dao.UserDAO;
// http://www.javacodegeeks.com/2012/05/secure-password-storage-donts-dos-and.html
@Singleton
public class PasswordEncryptionService {
private static final Logger log = LoggerFactory
.getLogger(UserDAO.class);
public boolean authenticate(String attemptedPassword,
byte[] encryptedPassword, byte[] salt) {
// Encrypt the clear-text password using the same salt that was used to
// encrypt the original password
byte[] encryptedAttemptedPassword = null;
try {
encryptedAttemptedPassword = getEncryptedPassword(
attemptedPassword, salt);
} catch (Exception e) {
// should never happen
log.error(e.getMessage(), e);
}
// Authentication succeeds if encrypted password that the user entered
// is equal to the stored hash
return Arrays.equals(encryptedPassword, encryptedAttemptedPassword);
}
public byte[] getEncryptedPassword(String password, byte[] salt) {
// PBKDF2 with SHA-1 as the hashing algorithm. Note that the NIST
// specifically names SHA-1 as an acceptable hashing algorithm for
// PBKDF2
String algorithm = "PBKDF2WithHmacSHA1";
// SHA-1 generates 160 bit hashes, so that's what makes sense here
int derivedKeyLength = 160;
// Pick an iteration count that works for you. The NIST recommends at
// least 1,000 iterations:
// http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
// iOS 4.x reportedly uses 10,000:
// http://blog.crackpassword.com/2010/09/smartphone-forensics-cracking-blackberry-backup-passwords/
int iterations = 20000;
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations,
derivedKeyLength);
byte[] bytes = null;
try {
SecretKeyFactory f = SecretKeyFactory.getInstance(algorithm);
SecretKey key = f.generateSecret(spec);
bytes = key.getEncoded();
} catch (Exception e) {
// should never happen
log.error(e.getMessage(), e);
}
return bytes;
}
public byte[] generateSalt() {
// VERY important to use SecureRandom instead of just Random
byte[] salt = null;
try {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
// Generate a 8 byte (64 bit) salt as recommended by RSA PKCS5
salt = new byte[8];
random.nextBytes(salt);
} catch (NoSuchAlgorithmException e) {
// should never happen
log.error(e.getMessage(), e);
}
return salt;
}
}

View File

@@ -0,0 +1,58 @@
package com.commafeed.backend.services;
import java.util.Collection;
import javax.ejb.Stateless;
import javax.inject.Inject;
import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole;
import com.commafeed.backend.model.UserRole.Role;
@Stateless
public class UserService {
@Inject
UserDAO userDAO;
@Inject
PasswordEncryptionService encryptionService;
public User login(String name, String password) {
User user = userDAO.findByName(name);
if (user != null && !user.isDisabled()) {
boolean authenticated = encryptionService.authenticate(password,
user.getPassword(), user.getSalt());
if (authenticated) {
return user;
}
}
return null;
}
public User register(String name, String password, Collection<Role> roles) {
return register(name, password, null, roles);
}
public User register(String name, String password, String email,
Collection<Role> roles) {
if (userDAO.findByName(name) != null) {
return null;
}
User user = new User();
byte[] salt = encryptionService.generateSalt();
user.setName(name);
user.setEmail(email);
user.setSalt(salt);
user.setPassword(encryptionService.getEncryptedPassword(password, salt));
user.getRoles().add(new UserRole(user, Role.USER));
for (Role role : roles) {
user.getRoles().add(new UserRole(user, role));
user.getRoles().add(new UserRole(user, role));
}
userDAO.save(user);
return user;
}
}