/* * Copyright 2005-2013 the original author or authors. * * 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.wamblee.photos.model.plumbing; import java.io.File; import java.io.IOException; import java.security.Principal; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Produces; import javax.inject.Inject; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.wamblee.cache.Cache; import org.wamblee.cache.EhCache; import org.wamblee.io.ClassPathResource; import org.wamblee.io.InputResource; import org.wamblee.photos.concurrent.ConcurrentAlbum; import org.wamblee.photos.model.Album; import org.wamblee.photos.model.PhotoEntry; import org.wamblee.photos.model.authorization.AuthorizedAlbum; import org.wamblee.photos.model.filesystem.FileSystemAlbum; import org.wamblee.photos.security.PageAuthorizationRule; import org.wamblee.photos.security.PhotoAuthorizationRule; import org.wamblee.photos.wicket.HomePage; import org.wamblee.security.authentication.GroupSet; import org.wamblee.security.authentication.Md5HexMessageDigester; import org.wamblee.security.authentication.MessageDigester; import org.wamblee.security.authentication.NameValidator; import org.wamblee.security.authentication.RegexpNameValidator; import org.wamblee.security.authentication.User; import org.wamblee.security.authentication.UserAccessor; import org.wamblee.security.authentication.UserAdminInitializer; import org.wamblee.security.authentication.UserAdministration; import org.wamblee.security.authentication.UserAdministrationImpl; import org.wamblee.security.authentication.UserSet; import org.wamblee.security.authentication.jpa.JpaGroupSet; import org.wamblee.security.authentication.jpa.JpaUserSet; import org.wamblee.security.authorization.AbstractAuthorizationRule; import org.wamblee.security.authorization.AllOperation; import org.wamblee.security.authorization.AnyUserCondition; import org.wamblee.security.authorization.AuthorizationInitializer; import org.wamblee.security.authorization.AuthorizationResult; import org.wamblee.security.authorization.AuthorizationService; import org.wamblee.security.authorization.CreateOperation; import org.wamblee.security.authorization.DefaultOperationRegistry; import org.wamblee.security.authorization.DeleteOperation; import org.wamblee.security.authorization.GroupUserCondition; import org.wamblee.security.authorization.Operation; import org.wamblee.security.authorization.OperationRegistry; import org.wamblee.security.authorization.ReadOperation; import org.wamblee.security.authorization.WriteOperation; import org.wamblee.security.authorization.jpa.JpaAuthorizationService; /** * @author Erik Brakkee * */ public class Producer { private static final Logger LOGGER = Logger.getLogger(Producer.class .getName()); private static final String APP_CONFIG_RESOURCE = "META-INF/org.wamblee.photos.properties"; @Inject private HttpServletRequest request; @Inject private HttpSession session; @PersistenceContext private EntityManager entityManager; // Created by this producer. @Inject private UserAdministration userAdmin; @Inject private AuthorizationService authorizationService; @Inject @AllPhotos private Album allPhotos; private Configuration getCOnfiguration() { LOGGER.info("Initializing configuration"); Configuration config; try { config = new Configuration(new ClassPathResource( APP_CONFIG_RESOURCE).getInputStream()); } catch (IOException e) { throw new RuntimeException( "Could not read application configuration property classpath resource " + APP_CONFIG_RESOURCE, e); } return config; } @Produces @ApplicationScoped public UserAdministration getUserAdmin() { LOGGER.info("Initializing user administration"); try { NameValidator passwordvalidator = new RegexpNameValidator(".{5,}", "INVALID_PASSWORD", "Password must have at least 5 characters"); InputResource cacheConfig = new ClassPathResource( "META-INF/ehcache.xml"); Cache userCache = new EhCache(cacheConfig, "users"); MessageDigester passwordEncoder = new Md5HexMessageDigester(); UserSet userset = new JpaUserSet(userCache, passwordvalidator, passwordEncoder, entityManager); GroupSet groupset = new JpaGroupSet(entityManager); NameValidator uservalidator = new RegexpNameValidator( "[a-zA-Z]+[a-zA-Z0-9]*", "INVALID_USERNAME", "User name must consist of alphanumeric characters only"); NameValidator groupvalidator = new RegexpNameValidator( "[a-zA-Z]+[a-zA-Z0-9]*", "INVALID_GROUPNAME", "Group name must consist of alphanumeric characters only"); UserAdministration admin = new UserAdministrationImpl(userset, groupset, uservalidator, groupvalidator); UserAdminInitializer initializer = new UserAdminInitializer(admin, new String[] { "erik", "admin" }, new String[] { "users", "administrators" }, new String[] { "abc123", "abc123" }); return admin; } catch (IOException e) { throw new RuntimeException( "Could not initialize user administration", e); } } @Produces @ApplicationScoped public AuthorizationService getAuthorizationService() { OperationRegistry registry = new DefaultOperationRegistry( new Operation[] { new AllOperation(), new CreateOperation(), new DeleteOperation(), new ReadOperation(), new WriteOperation() }); UserAccessor userAccessor = new UserAccessor() { @Override public String getCurrentUser() { Principal principal = request.getUserPrincipal(); if (principal == null) { return null; } return principal.getName(); } }; AuthorizationService service = new JpaAuthorizationService("DEFAULT", entityManager, userAccessor, userAdmin, 10000); AnyUserCondition anyUserCondition = new AnyUserCondition(); GroupUserCondition adminUserCondition = new GroupUserCondition( "administrators"); PhotoAuthorizationRule photoEntryRule = new PhotoAuthorizationRule(); // Pages that allow access by any authenticated user PageAuthorizationRule anyUserPageRule = new PageAuthorizationRule( AuthorizationResult.GRANTED, anyUserCondition, HomePage.class); PageAuthorizationRule adminPageRule = new PageAuthorizationRule( AuthorizationResult.GRANTED, adminUserCondition); AuthorizationInitializer initializer = new AuthorizationInitializer( service, new AbstractAuthorizationRule[] { photoEntryRule, anyUserPageRule, adminPageRule }); return service; } @Produces @ApplicationScoped @AllPhotos public Album getAllPhotos() { LOGGER.info("Initializing photo album"); try { File dir = new File(getCOnfiguration().getPath()); InputResource cacheConfig = new ClassPathResource( "META-INF/ehcache.xml"); Cache> photoCache = new EhCache>( cacheConfig, "photos"); Album fileSystemAlbum = new FileSystemAlbum(dir, "/", photoCache); Album concurrentAlbum = new ConcurrentAlbum(fileSystemAlbum); return concurrentAlbum; } catch (IOException e) { throw new RuntimeException("Could not initialize photo album", e); } } @Produces @SessionScoped @AuthorizedPhotos public Album getAuthorizedAlbum() { LOGGER.info("Initializing authorized photos for current session"); try { InputResource cacheConfig = new ClassPathResource( "META-INF/ehcache.xml"); Cache userCache = new EhCache(cacheConfig, "users"); Cache authorizedPhotoCache = new EhCache(cacheConfig, "photos"); AuthorizedAlbum album = new AuthorizedAlbum(allPhotos, authorizationService, authorizedPhotoCache, session.getId()); return album; } catch (IOException e) { throw new RuntimeException("Problem initializing authorized album", e); } } @Produces @SessionScoped public User getUser() { LOGGER.info("Initializing user object for current session"); Principal userPrincipal = request.getUserPrincipal(); if (userPrincipal == null) { // CDI: cannot return null from this method. throw new RuntimeException("No authenticated user"); } String username = userPrincipal.getName(); List users = entityManager .createNamedQuery(User.QUERY_FIND_BY_NAME) .setParameter(User.NAME_PARAM, username).getResultList(); if (users.size() > 1) { throw new RuntimeException("More than one user found for '" + username + "'"); } if (users.isEmpty()) { throw new RuntimeException("No authenticated user"); } return users.get(0); } }