added authentication via api key for some limited api methods (fix #64)

This commit is contained in:
Athou
2013-05-01 21:56:59 +02:00
parent 52a8ea1920
commit 5dcc923cf1
14 changed files with 148 additions and 40 deletions

View File

@@ -97,7 +97,7 @@ public abstract class AbstractREST {
@Inject
OPMLImporter opmlImporter;
@Inject
OPMLExporter opmlExporter;
@@ -124,44 +124,61 @@ public abstract class AbstractREST {
.fetchCreateAndSetSession(cycle);
if (session.getUser() == null) {
IAuthenticationStrategy authenticationStrategy = app
.getSecuritySettings().getAuthenticationStrategy();
String[] data = authenticationStrategy.load();
cookieLogin(app, session);
}
if (session.getUser() == null) {
basicHttpLogin(swreq, session);
}
}
private void cookieLogin(CommaFeedApplication app, CommaFeedSession session) {
IAuthenticationStrategy authenticationStrategy = app
.getSecuritySettings().getAuthenticationStrategy();
String[] data = authenticationStrategy.load();
if (data != null && data.length > 1) {
session.signIn(data[0], data[1]);
}
}
private void basicHttpLogin(ServletWebRequest req, CommaFeedSession session) {
String value = req.getHeader(HttpHeaders.AUTHORIZATION);
if (value != null && value.startsWith("Basic ")) {
value = value.substring(6);
String decoded = new String(Base64.decodeBase64(value));
String[] data = decoded.split(":");
if (data != null && data.length > 1) {
session.signIn(data[0], data[1]);
} else {
String value = swreq.getHeader(HttpHeaders.AUTHORIZATION);
if (value != null && value.startsWith("Basic ")) {
value = value.substring(6);
String decoded = new String(Base64.decodeBase64(value));
data = decoded.split(":");
if (data != null && data.length > 1) {
session.signIn(data[0], data[1]);
}
}
}
}
}
private void apiKeyLogin() {
String apiKey = request.getParameter("apiKey");
User user = userDAO.findByApiKey(apiKey);
CommaFeedSession.get().setUser(user);
}
protected User getUser() {
return CommaFeedSession.get().getUser();
}
@AroundInvoke
public Object checkSecurity(InvocationContext context) throws Exception {
User user = getUser();
boolean allowed = true;
User user = null;
Method method = context.getMethod();
SecurityCheck check = method.isAnnotationPresent(SecurityCheck.class) ? method
.getAnnotation(SecurityCheck.class) : method
.getDeclaringClass().getAnnotation(SecurityCheck.class);
if (method.isAnnotationPresent(SecurityCheck.class)) {
allowed = checkRole(user, method.getAnnotation(SecurityCheck.class));
} else if (method.getDeclaringClass().isAnnotationPresent(
SecurityCheck.class)) {
allowed = checkRole(
user,
method.getDeclaringClass().getAnnotation(
SecurityCheck.class));
if (check != null) {
user = getUser();
if (user == null && check.apiKeyAllowed()) {
apiKeyLogin();
user = getUser();
}
allowed = checkRole(check.value());
}
if (!allowed) {
if (user == null) {
@@ -181,8 +198,7 @@ public abstract class AbstractREST {
return context.proceed();
}
private boolean checkRole(User user, SecurityCheck annotation) {
Role requiredRole = annotation.value();
private boolean checkRole(Role requiredRole) {
if (requiredRole == Role.NONE) {
return true;
}

View File

@@ -26,7 +26,9 @@ import org.slf4j.LoggerFactory;
import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.model.UserSettings.ReadingOrder;
import com.commafeed.frontend.SecurityCheck;
import com.commafeed.frontend.model.Category;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.Entry;
@@ -111,6 +113,7 @@ public class CategoryREST extends AbstractResourceREST {
@GET
@ApiOperation(value = "Get category entries as feed", notes = "Get a feed of category entries")
@Produces(MediaType.APPLICATION_XML)
@SecurityCheck(value = Role.USER, apiKeyAllowed = true)
public String getCategoryEntriesAsFeed(
@ApiParam(value = "id of the category, 'all' or 'starred'", required = true) @QueryParam("id") String id) {

View File

@@ -31,14 +31,16 @@ import com.commafeed.backend.feeds.FetchedFeed;
import com.commafeed.backend.model.FeedCategory;
import com.commafeed.backend.model.FeedEntryStatus;
import com.commafeed.backend.model.FeedSubscription;
import com.commafeed.backend.model.UserRole.Role;
import com.commafeed.backend.model.UserSettings.ReadingOrder;
import com.commafeed.frontend.SecurityCheck;
import com.commafeed.frontend.model.Entries;
import com.commafeed.frontend.model.Entry;
import com.commafeed.frontend.model.FeedInfo;
import com.commafeed.frontend.model.Subscription;
import com.commafeed.frontend.model.request.FeedModificationRequest;
import com.commafeed.frontend.model.request.IDRequest;
import com.commafeed.frontend.model.request.MarkRequest;
import com.commafeed.frontend.model.request.FeedModificationRequest;
import com.commafeed.frontend.model.request.SubscribeRequest;
import com.commafeed.frontend.rest.Enums.ReadType;
import com.google.common.base.Preconditions;
@@ -98,6 +100,7 @@ public class FeedREST extends AbstractResourceREST {
@GET
@ApiOperation(value = "Get feed entries as a feed", notes = "Get a feed of feed entries")
@Produces(MediaType.APPLICATION_XML)
@SecurityCheck(value = Role.USER, apiKeyAllowed = true)
public String getFeedEntriesAsFeed(
@ApiParam(value = "id of the feed", required = true) @QueryParam("id") String id) {

View File

@@ -1,11 +1,14 @@
package com.commafeed.frontend.rest.resources;
import java.util.UUID;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import com.commafeed.backend.StartupBean;
@@ -78,6 +81,7 @@ public class UserREST extends AbstractResourceREST {
userModel.setName(user.getName());
userModel.setEmail(user.getEmail());
userModel.setEnabled(!user.isDisabled());
userModel.setApiKey(user.getApiKey());
for (UserRole role : userRoleDAO.findAll(user)) {
if (role.getRole() == Role.ADMIN) {
userModel.setAdmin(true);
@@ -95,13 +99,24 @@ public class UserREST extends AbstractResourceREST {
if (StartupBean.USERNAME_DEMO.equals(user.getName())) {
return Response.status(Status.UNAUTHORIZED).build();
}
user.setEmail(request.getEmail());
if (StringUtils.isNotBlank(request.getPassword())) {
byte[] password = encryptionService.getEncryptedPassword(
request.getPassword(), user.getSalt());
user.setPassword(password);
user.setApiKey(generateKey(user));
}
if (request.isNewApiKey()) {
user.setApiKey(generateKey(user));
}
userDAO.update(user);
return Response.ok().build();
}
private String generateKey(User user) {
byte[] key = encryptionService.getEncryptedPassword(UUID.randomUUID()
.toString(), user.getSalt());
return DigestUtils.sha1Hex(key);
}
}