001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.core.util.crypt;
018
019import java.io.Serializable;
020
021import org.apache.wicket.MetaDataKey;
022import org.apache.wicket.Session;
023import org.apache.wicket.util.crypt.ICrypt;
024import org.apache.wicket.util.crypt.ICryptFactory;
025import org.apache.wicket.util.io.IClusterable;
026
027
028/**
029 * Base class to implement crypt factories that store crypt into user session. Note that the use of
030 * this crypt factory will result in an immediate creation of a http session.
031 * 
032 * @author andrea del bene
033 *
034 * @param <T>
035 *            the type for the secret key.
036 */
037public abstract class AbstractKeyInSessionCryptFactory<T extends IClusterable>
038        implements
039                ICryptFactory
040{
041        /** metadata-key used to store crypto-key in session metadata */
042        private static final MetaDataKey<Serializable> KEY = new MetaDataKey<>()
043        {
044                private static final long serialVersionUID = 1L;
045        };
046
047        /**
048         * Creates a new crypt for the current user session. If no user session is available, a new one
049         * is created.
050         * 
051         * @return
052         */
053        @Override
054        public ICrypt newCrypt()
055        {
056                Session session = Session.get();
057                session.bind();
058
059                // retrieve or generate encryption key from session
060                T key = (T) session.getMetaData(KEY);
061                if (key == null)
062                {
063                        // generate new key
064                        key = generateKey(session);
065                        session.setMetaData(KEY, key);
066                }
067
068                // build the crypt based on session key
069                ICrypt crypt = createCrypt(key);
070                return crypt;
071        }
072
073        /**
074         * Generates the secret key for a new crypt.
075         * 
076         * @param session
077         *            the current user session where crypt will be stored
078         * @return the secret key for a new crypt
079         */
080        protected abstract T generateKey(Session session);
081
082        /**
083         * @return the {@link org.apache.wicket.util.crypt.ICrypt} to use
084         */
085        protected abstract ICrypt createCrypt(T key);
086}