http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/ServerMain.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/ServerMain.java b/src/org/waveprotocol/box/server/ServerMain.java deleted file mode 100644 index 50a8b7c..0000000 --- a/src/org/waveprotocol/box/server/ServerMain.java +++ /dev/null @@ -1,287 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server; - -import cc.kune.initials.InitialsAvatarsServlet; -import com.google.gwt.logging.server.RemoteLoggingServiceImpl; -import com.google.inject.*; -import com.google.inject.name.Names; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigFactory; -import org.apache.commons.configuration.ConfigurationException; -import org.eclipse.jetty.proxy.ProxyServlet; -import org.waveprotocol.box.common.comms.WaveClientRpc.ProtocolWaveClientRpc; -import org.waveprotocol.box.server.authentication.AccountStoreHolder; -import org.waveprotocol.box.server.authentication.SessionManager; -import org.waveprotocol.box.server.executor.ExecutorsModule; -import org.waveprotocol.box.server.frontend.ClientFrontend; -import org.waveprotocol.box.server.frontend.ClientFrontendImpl; -import org.waveprotocol.box.server.frontend.WaveClientRpcImpl; -import org.waveprotocol.box.server.frontend.WaveletInfo; -import org.waveprotocol.box.server.persistence.AccountStore; -import org.waveprotocol.box.server.persistence.PersistenceException; -import org.waveprotocol.box.server.persistence.PersistenceModule; -import org.waveprotocol.box.server.persistence.SignerInfoStore; -import org.waveprotocol.box.server.robots.ProfileFetcherModule; -import org.waveprotocol.box.server.robots.RobotApiModule; -import org.waveprotocol.box.server.robots.RobotRegistrationServlet; -import org.waveprotocol.box.server.robots.active.ActiveApiServlet; -import org.waveprotocol.box.server.robots.agent.passwd.PasswordAdminRobot; -import org.waveprotocol.box.server.robots.agent.passwd.PasswordRobot; -import org.waveprotocol.box.server.robots.agent.registration.RegistrationRobot; -import org.waveprotocol.box.server.robots.agent.welcome.WelcomeRobot; -import org.waveprotocol.box.server.robots.dataapi.DataApiOAuthServlet; -import org.waveprotocol.box.server.robots.dataapi.DataApiServlet; -import org.waveprotocol.box.server.robots.passive.RobotsGateway; -import org.waveprotocol.box.server.rpc.*; -import org.waveprotocol.box.server.stat.RequestScopeFilter; -import org.waveprotocol.box.server.stat.StatuszServlet; -import org.waveprotocol.box.server.stat.TimingFilter; -import org.waveprotocol.box.server.waveserver.*; -import org.waveprotocol.box.stat.StatService; -import org.waveprotocol.wave.crypto.CertPathStore; -import org.waveprotocol.wave.federation.FederationTransport; -import org.waveprotocol.wave.federation.noop.NoOpFederationModule; -import org.waveprotocol.wave.federation.xmpp.XmppFederationModule; -import org.waveprotocol.wave.model.version.HashedVersionFactory; -import org.waveprotocol.wave.model.wave.ParticipantIdUtil; -import org.waveprotocol.wave.util.logging.Log; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServlet; -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Map; - -/** - * Wave Server entrypoint. - */ -public class ServerMain { - - private static final Log LOG = Log.get(ServerMain.class); - - @SuppressWarnings("serial") - @Singleton - public static class GadgetProxyServlet extends HttpServlet { - - ProxyServlet.Transparent proxyServlet; - - @Inject - public GadgetProxyServlet(Config config) { - String gadgetServerHostname = config.getString("core.gadget_server_hostname"); - int gadgetServerPort = config.getInt("core.gadget_server_port"); - LOG.info("Starting GadgetProxyServlet for " + gadgetServerHostname + ":" + gadgetServerPort); - proxyServlet = new ProxyServlet.Transparent( - "http://" + gadgetServerHostname + ":" + gadgetServerPort + "/gadgets", - "/gadgets"); - } - - @Override - public void init(ServletConfig config) throws ServletException { - proxyServlet.init(config); - } - - @Override - public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { - proxyServlet.service(req, res); - } - } - - public static void main(String... args) { - try { - Module coreSettings = new AbstractModule() { - - @Override - protected void configure() { - Config config = - ConfigFactory.load().withFallback( - ConfigFactory.parseFile(new File("application.conf")).withFallback( - ConfigFactory.parseFile(new File("reference.conf")))); - bind(Config.class).toInstance(config); - bind(Key.get(String.class, Names.named(CoreSettingsNames.WAVE_SERVER_DOMAIN))) - .toInstance(config.getString("core.wave_server_domain")); - } - }; - run(coreSettings); - } catch (PersistenceException e) { - LOG.severe("PersistenceException when running server:", e); - } catch (ConfigurationException e) { - LOG.severe("ConfigurationException when running server:", e); - } catch (WaveServerException e) { - LOG.severe("WaveServerException when running server:", e); - } - } - - public static void run(Module coreSettings) throws PersistenceException, - ConfigurationException, WaveServerException { - Injector injector = Guice.createInjector(coreSettings); - Module profilingModule = injector.getInstance(StatModule.class); - ExecutorsModule executorsModule = injector.getInstance(ExecutorsModule.class); - injector = injector.createChildInjector(profilingModule, executorsModule); - - Config config = injector.getInstance(Config.class); - boolean enableFederation = config.getBoolean("federation.enable_federation"); - - Module serverModule = injector.getInstance(ServerModule.class); - Module federationModule = buildFederationModule(injector, enableFederation); - Module robotApiModule = new RobotApiModule(); - PersistenceModule persistenceModule = injector.getInstance(PersistenceModule.class); - Module searchModule = injector.getInstance(SearchModule.class); - Module profileFetcherModule = injector.getInstance(ProfileFetcherModule.class); - injector = injector.createChildInjector(serverModule, persistenceModule, robotApiModule, - federationModule, searchModule, profileFetcherModule); - - ServerRpcProvider server = injector.getInstance(ServerRpcProvider.class); - WaveBus waveBus = injector.getInstance(WaveBus.class); - - String domain = config.getString("core.wave_server_domain"); - if (!ParticipantIdUtil.isDomainAddress(ParticipantIdUtil.makeDomainAddress(domain))) { - throw new WaveServerException("Invalid wave domain: " + domain); - } - - initializeServer(injector, domain); - initializeServlets(server, config); - initializeRobotAgents(server); - initializeRobots(injector, waveBus); - initializeFrontend(injector, server, waveBus); - initializeFederation(injector); - initializeSearch(injector, waveBus); - - LOG.info("Starting server"); - server.startWebSocketServer(injector); - } - - private static Module buildFederationModule(Injector settingsInjector, boolean enableFederation) - throws ConfigurationException { - Module federationModule; - if (enableFederation) { - federationModule = settingsInjector.getInstance(XmppFederationModule.class); - } else { - federationModule = settingsInjector.getInstance(NoOpFederationModule.class); - } - return federationModule; - } - - private static void initializeServer(Injector injector, String waveDomain) - throws PersistenceException, WaveServerException { - AccountStore accountStore = injector.getInstance(AccountStore.class); - accountStore.initializeAccountStore(); - AccountStoreHolder.init(accountStore, waveDomain); - - // Initialize the SignerInfoStore. - CertPathStore certPathStore = injector.getInstance(CertPathStore.class); - if (certPathStore instanceof SignerInfoStore) { - ((SignerInfoStore)certPathStore).initializeSignerInfoStore(); - } - - // Initialize the server. - WaveletProvider waveServer = injector.getInstance(WaveletProvider.class); - waveServer.initialize(); - } - - private static void initializeServlets(ServerRpcProvider server, Config config) { - server.addServlet("/gadget/gadgetlist", GadgetProviderServlet.class); - - server.addServlet(AttachmentServlet.ATTACHMENT_URL + "/*", AttachmentServlet.class); - server.addServlet(AttachmentServlet.THUMBNAIL_URL + "/*", AttachmentServlet.class); - server.addServlet(AttachmentInfoServlet.ATTACHMENTS_INFO_URL, AttachmentInfoServlet.class); - - server.addServlet(SessionManager.SIGN_IN_URL, AuthenticationServlet.class); - server.addServlet("/auth/signout", SignOutServlet.class); - server.addServlet("/auth/register", UserRegistrationServlet.class); - - server.addServlet("/locale/*", LocaleServlet.class); - server.addServlet("/fetch/*", FetchServlet.class); - server.addServlet("/search/*", SearchServlet.class); - server.addServlet("/notification/*", NotificationServlet.class); - - server.addServlet("/robot/dataapi", DataApiServlet.class); - server.addServlet(DataApiOAuthServlet.DATA_API_OAUTH_PATH + "/*", DataApiOAuthServlet.class); - server.addServlet("/robot/dataapi/rpc", DataApiServlet.class); - server.addServlet("/robot/register/*", RobotRegistrationServlet.class); - server.addServlet("/robot/rpc", ActiveApiServlet.class); - server.addServlet("/webclient/remote_logging", RemoteLoggingServiceImpl.class); - server.addServlet("/profile/*", FetchProfilesServlet.class); - server.addServlet("/iniavatars/*", InitialsAvatarsServlet.class); - server.addServlet("/waveref/*", WaveRefServlet.class); - - String gadgetHostName = config.getString("core.gadget_server_hostname"); - int port = config.getInt("core.gadget_server_port"); - Map<String, String> initParams = - Collections.singletonMap("hostHeader", gadgetHostName + ":" + port); - server.addServlet("/gadgets/*", GadgetProxyServlet.class, initParams); - - server.addServlet("/", WaveClientServlet.class); - - // Profiling - server.addFilter("/*", RequestScopeFilter.class); - boolean enableProfiling = config.getBoolean("core.enable_profiling"); - if (enableProfiling) { - server.addFilter("/*", TimingFilter.class); - server.addServlet(StatService.STAT_URL, StatuszServlet.class); - } - } - - private static void initializeRobots(Injector injector, WaveBus waveBus) { - RobotsGateway robotsGateway = injector.getInstance(RobotsGateway.class); - waveBus.subscribe(robotsGateway); - } - - private static void initializeRobotAgents(ServerRpcProvider server) { - server.addServlet(PasswordRobot.ROBOT_URI + "/*", PasswordRobot.class); - server.addServlet(PasswordAdminRobot.ROBOT_URI + "/*", PasswordAdminRobot.class); - server.addServlet(WelcomeRobot.ROBOT_URI + "/*", WelcomeRobot.class); - server.addServlet(RegistrationRobot.ROBOT_URI + "/*", RegistrationRobot.class); - } - - private static void initializeFrontend(Injector injector, ServerRpcProvider server, - WaveBus waveBus) throws WaveServerException { - HashedVersionFactory hashFactory = injector.getInstance(HashedVersionFactory.class); - - WaveletProvider provider = injector.getInstance(WaveletProvider.class); - WaveletInfo waveletInfo = WaveletInfo.create(hashFactory, provider); - ClientFrontend frontend = - ClientFrontendImpl.create(provider, waveBus, waveletInfo); - - ProtocolWaveClientRpc.Interface rpcImpl = WaveClientRpcImpl.create(frontend, false); - server.registerService(ProtocolWaveClientRpc.newReflectiveService(rpcImpl)); - } - - private static void initializeFederation(Injector injector) { - FederationTransport federationManager = injector.getInstance(FederationTransport.class); - federationManager.startFederation(); - } - - private static void initializeSearch(Injector injector, WaveBus waveBus) - throws WaveServerException { - PerUserWaveViewDistpatcher waveViewDistpatcher = - injector.getInstance(PerUserWaveViewDistpatcher.class); - PerUserWaveViewBus.Listener listener = injector.getInstance(PerUserWaveViewBus.Listener.class); - waveViewDistpatcher.addListener(listener); - waveBus.subscribe(waveViewDistpatcher); - - WaveIndexer waveIndexer = injector.getInstance(WaveIndexer.class); - waveIndexer.remakeIndex(); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/ServerModule.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/ServerModule.java b/src/org/waveprotocol/box/server/ServerModule.java deleted file mode 100644 index c96ab1c..0000000 --- a/src/org/waveprotocol/box/server/ServerModule.java +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server; - -import com.google.inject.AbstractModule; -import com.google.inject.Inject; -import com.google.inject.Provides; -import com.google.inject.Singleton; -import com.google.inject.TypeLiteral; -import com.google.inject.name.Named; -import com.google.inject.name.Names; - -import com.typesafe.config.Config; -import org.eclipse.jetty.server.session.HashSessionManager; -import org.waveprotocol.box.server.authentication.SessionManager; -import org.waveprotocol.box.server.authentication.SessionManagerImpl; -import org.waveprotocol.box.server.robots.register.RobotRegistrar; -import org.waveprotocol.box.server.robots.register.RobotRegistrarImpl; -import org.waveprotocol.box.server.rpc.ProtoSerializer; -import org.waveprotocol.box.server.rpc.ServerRpcProvider; -import org.waveprotocol.box.server.rpc.WebSocketChannel; -import org.waveprotocol.box.server.waveserver.WaveServerImpl; -import org.waveprotocol.box.server.waveserver.WaveServerModule; -import org.waveprotocol.wave.federation.FederationHostBridge; -import org.waveprotocol.wave.federation.FederationRemoteBridge; -import org.waveprotocol.wave.federation.WaveletFederationListener; -import org.waveprotocol.wave.federation.WaveletFederationProvider; -import org.waveprotocol.wave.model.id.IdGenerator; -import org.waveprotocol.wave.model.id.IdGeneratorImpl; -import org.waveprotocol.wave.model.id.IdGeneratorImpl.Seed; -import org.waveprotocol.wave.model.id.TokenGenerator; -import org.waveprotocol.wave.model.id.TokenGeneratorImpl; - -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.List; - -import javax.security.auth.login.Configuration; - -/** - * Guice Module for the prototype Server. - * - * - */ -public class ServerModule extends AbstractModule { - private final WaveServerModule waveServerModule; - - @Inject - public ServerModule(WaveServerModule waveServerModule) { - this.waveServerModule = waveServerModule; - } - - @Override - protected void configure() { - bind(WaveServerImpl.class).in(Singleton.class); - // Receive updates from the outside world, and push them into our local Wave - // Server. - bind(WaveletFederationListener.Factory.class).annotatedWith(FederationRemoteBridge.class).to( - WaveServerImpl.class); - - // Provide history and respond to submits about our own local waves. - bind(WaveletFederationProvider.class).annotatedWith(FederationHostBridge.class).to( - WaveServerImpl.class); - - install(waveServerModule); - TypeLiteral<List<String>> certs = new TypeLiteral<List<String>>() {}; - bind(certs).annotatedWith(Names.named("certs")).toInstance(Arrays.<String> asList()); - - bind(ProtoSerializer.class).in(Singleton.class); - - bind(Configuration.class).toInstance(Configuration.getConfiguration()); - bind(SessionManager.class).to(SessionManagerImpl.class).in(Singleton.class); - - bind(ServerRpcProvider.class).in(Singleton.class); - - bind(RobotRegistrar.class).to(RobotRegistrarImpl.class); - - requestStaticInjection(WebSocketChannel.class); - } - - @Provides - @Singleton - public IdGenerator provideIdGenerator(@Named(CoreSettingsNames.WAVE_SERVER_DOMAIN) String domain, - Seed seed) { - return new IdGeneratorImpl(domain, seed); - } - - @Provides - @Singleton - public SecureRandom provideSecureRandom() { - return new SecureRandom(); - } - - @Provides - @Singleton - public TokenGenerator provideTokenGenerator(SecureRandom random) { - return new TokenGeneratorImpl(random); - } - - @Provides - @Singleton - public Seed provideSeed(final SecureRandom random) { - return new Seed() { - @Override - public String get() { - return Long.toString(Math.abs(random.nextLong()), 36); - } - }; - } - - @Provides - @Singleton - public org.eclipse.jetty.server.SessionManager provideSessionManager(Config config) { - HashSessionManager sessionManager = new HashSessionManager(); - sessionManager.getSessionCookieConfig().setMaxAge(config.getInt("network.session_cookie_max_age")); - return sessionManager; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/StatModule.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/StatModule.java b/src/org/waveprotocol/box/server/StatModule.java deleted file mode 100644 index bcd0e0f..0000000 --- a/src/org/waveprotocol/box/server/StatModule.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server; - -import com.google.inject.AbstractModule; -import com.google.inject.Inject; -import static com.google.inject.matcher.Matchers.annotatedWith; -import static com.google.inject.matcher.Matchers.any; -import com.google.inject.name.Named; -import com.typesafe.config.Config; -import org.waveprotocol.box.server.stat.MultiThreadedRequestScope; - -import org.waveprotocol.box.server.stat.TimingInterceptor; - -import org.waveprotocol.box.stat.Timed; -import org.waveprotocol.box.stat.Timing; - -/** - * @author [email protected] (Dhanji R. Prasanna) - * @author [email protected] (A. Kaplanov) - */ -public class StatModule extends AbstractModule { - private final boolean enableProfiling; - - @Inject - public StatModule(Config config) { - this.enableProfiling = config.getBoolean("core.enable_profiling"); - } - - @Override - protected void configure() { - TimingInterceptor interceptor = new TimingInterceptor(); - requestInjection(interceptor); - if (enableProfiling) { - bindInterceptor(any(), annotatedWith(Timed.class), interceptor); - } - Timing.setScope(new MultiThreadedRequestScope()); - Timing.setEnabled(enableProfiling); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/account/AccountData.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/account/AccountData.java b/src/org/waveprotocol/box/server/account/AccountData.java deleted file mode 100644 index 560e8f7..0000000 --- a/src/org/waveprotocol/box/server/account/AccountData.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.account; - -import org.waveprotocol.wave.model.wave.ParticipantId; - - -/** - * Represents a basic immutable account, consists solely out of a username. It - * has methods to check and convert to other type of accounts. - * - * @author [email protected] (Lennard de Rijk) - */ -public interface AccountData { - - /** - * Gets the participant id of the user who owns this account. This is the - * primary identifier for accounts. - * - * @return returns a non-null participant id. - */ - ParticipantId getId(); - - /** - * @return true iff this account is a {@link HumanAccountData}. - */ - boolean isHuman(); - - /** - * Returns this account as a {@link HumanAccountData}. - * - * @precondition isHuman() - */ - HumanAccountData asHuman(); - - /** - * @return true iff this account is a {@link RobotAccountData}. - */ - boolean isRobot(); - - /** - * Returns this account as a {@link RobotAccountData}. - * - * @precondition isRobot() - */ - RobotAccountData asRobot(); -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/account/HumanAccountData.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/account/HumanAccountData.java b/src/org/waveprotocol/box/server/account/HumanAccountData.java deleted file mode 100644 index 84431ec..0000000 --- a/src/org/waveprotocol/box/server/account/HumanAccountData.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.account; - -import org.waveprotocol.box.server.authentication.PasswordDigest; - -/** - * {@link HumanAccountData} representing an account from a human. - * - * Stores the user's authentication information. - * - * @author [email protected] (Lennard de Rijk) - * @author [email protected] (Joseph Gentle) - * @author [email protected] (Andrew Kaplanov) - */ -public interface HumanAccountData extends AccountData { - /** - * Gets the user's password digest. The digest can be used to authenticate the - * user. - * - * This method will return null if password based authentication is disabled - * for the user, or if no password is set. - * - * @return The user's password digest, or null if password authentication is - * disabled for the user, or no password is set. - */ - PasswordDigest getPasswordDigest(); - - /** - * Gets user's locale. - * - * @return The user's locale. - */ - String getLocale(); - - /** - * Sets the user's locale. - * - */ - void setLocale(String locale); -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/account/HumanAccountDataImpl.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/account/HumanAccountDataImpl.java b/src/org/waveprotocol/box/server/account/HumanAccountDataImpl.java deleted file mode 100644 index d773acb..0000000 --- a/src/org/waveprotocol/box/server/account/HumanAccountDataImpl.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.account; - -import com.google.common.base.Preconditions; - -import org.waveprotocol.box.server.authentication.PasswordDigest; -import org.waveprotocol.wave.model.wave.ParticipantId; - -/** - * Human Account. Expected to be expanded when authentication is implemented. - * - * @author [email protected] (Lennard de Rijk) - * @author [email protected] (Andrew kaplanov) - */ -public final class HumanAccountDataImpl implements HumanAccountData { - private final ParticipantId id; - private final PasswordDigest passwordDigest; - private String locale; - - /** - * Creates an {@link HumanAccountData} for the given username, with no - * password. - * - * This user will not be able to login using password-bsed authentication. - * - * @param id non-null participant id for this account. - */ - public HumanAccountDataImpl(ParticipantId id) { - this(id, null); - } - - /** - * Creates an {@link HumanAccountData} for the given participant. - * - * @param id non-null participant id for this account. - * @param passwordDigest The user's password digest, or null if the user - * should not be authenticated using a password. This is typically - * obtained by calling {@code new PasswordDigest(password_chars);} - */ - public HumanAccountDataImpl(ParticipantId id, PasswordDigest passwordDigest) { - Preconditions.checkNotNull(id, "Id can not be null"); - - this.id = id; - this.passwordDigest = passwordDigest; - } - - @Override - public ParticipantId getId() { - return id; - } - - @Override - public PasswordDigest getPasswordDigest() { - return passwordDigest; - } - - @Override - public String getLocale() { - return locale; - } - - @Override - public void setLocale(String locale) { - this.locale = locale; - } - - @Override - public boolean isHuman() { - return true; - } - - @Override - public HumanAccountData asHuman() { - return this; - } - - @Override - public boolean isRobot() { - return false; - } - - @Override - public RobotAccountData asRobot() { - throw new UnsupportedOperationException("Can't turn a HumanAccount into a RobotAccount"); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((passwordDigest == null) ? 0 : passwordDigest.hashCode()); - result = prime * result + ((locale == null) ? 0 : locale.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof HumanAccountDataImpl)) return false; - HumanAccountDataImpl other = (HumanAccountDataImpl) obj; - if (id == null) { - if (other.id != null) return false; - } else if (!id.equals(other.id)) return false; - if (passwordDigest == null) { - if (other.passwordDigest != null) return false; - } else if (!passwordDigest.equals(other.passwordDigest)) return false; - if (locale == null) { - if (other.locale != null) return false; - } else if (!locale.equals(other.locale)) return false; - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/account/RobotAccountData.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/account/RobotAccountData.java b/src/org/waveprotocol/box/server/account/RobotAccountData.java deleted file mode 100644 index 34bc83e..0000000 --- a/src/org/waveprotocol/box/server/account/RobotAccountData.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.account; - -import org.waveprotocol.box.server.robots.RobotCapabilities; - -/** - * Represents an {@link AccountData} belonging to a Robot. - * - * @author [email protected] (Lennard de Rijk) - * - */ -public interface RobotAccountData extends AccountData { - - /** - * Returns the URL on which the robot can be located. The URL must not end - * with /. - */ - String getUrl(); - - /** - * The consumer secret used in OAuth of the Robot. The consumer key is equal - * to {@link RobotAccountData#getId()}. - */ - String getConsumerSecret(); - - /** - * The capabilities that have been retrieved from a robot's capabilities.xml - * file. May be null if they have not been retrieved. - */ - RobotCapabilities getCapabilities(); - - /** - * Returns true iff the robot ownership has been verified and is ready to be - * used in the Robot API. - */ - boolean isVerified(); -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/account/RobotAccountDataImpl.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/account/RobotAccountDataImpl.java b/src/org/waveprotocol/box/server/account/RobotAccountDataImpl.java deleted file mode 100644 index 0ddbc5f..0000000 --- a/src/org/waveprotocol/box/server/account/RobotAccountDataImpl.java +++ /dev/null @@ -1,179 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.account; - -import com.google.common.base.Preconditions; - -import org.waveprotocol.box.server.robots.RobotCapabilities; -import org.waveprotocol.wave.model.wave.ParticipantId; - -/** - * Robot Account implementation. - * - * @author [email protected] (Lennard de Rijk) - */ -public final class RobotAccountDataImpl implements RobotAccountData { - private final ParticipantId id; - private final String url; - private final String consumerSecret; - private final RobotCapabilities capabilities; - private final boolean isVerified; - - /** - * Creates a new {@link RobotAccountData}. - * - * The capabilities map and version may only be null if the capabilitiesHash - * is null and vice versa. - * - * @param id non-null participant id for this account. - * @param url non-null url where the robot can be reached. - * @param consumerSecret non-null consumer secret used in OAuth. - * @param capabilities {@link RobotCapabilities} representing the robot's - * capabilties.xml. May be null. - * @param isVerified boolean indicating whether this {@link RobotAccountData} - * has been verified. - */ - public RobotAccountDataImpl(ParticipantId id, String url, String consumerSecret, - RobotCapabilities capabilities, boolean isVerified) { - Preconditions.checkNotNull(id, "Id can not be null"); - Preconditions.checkNotNull(url, "Url can not be null"); - Preconditions.checkNotNull(consumerSecret, "Consumer secret can not be null"); - Preconditions.checkArgument(!url.endsWith("/"), "Url must not end with /"); - - this.id = id; - this.url = url; - this.consumerSecret = consumerSecret; - this.capabilities = capabilities; - this.isVerified = isVerified; - } - - @Override - public ParticipantId getId() { - return id; - } - - @Override - public boolean isHuman() { - return false; - } - - @Override - public HumanAccountData asHuman() { - throw new UnsupportedOperationException("Can't turn a RobotAccount into a HumanAccount"); - } - - @Override - public boolean isRobot() { - return true; - } - - @Override - public RobotAccountData asRobot() { - return this; - } - - @Override - public String getUrl() { - return url; - } - - @Override - public String getConsumerSecret() { - return consumerSecret; - } - - @Override - public RobotCapabilities getCapabilities() { - return capabilities; - } - - @Override - public boolean isVerified() { - return isVerified; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode()); - result = prime * result + ((consumerSecret == null) ? 0 : consumerSecret.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + (isVerified ? 1231 : 1237); - result = prime * result + ((url == null) ? 0 : url.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof RobotAccountDataImpl)) { - return false; - } - RobotAccountDataImpl other = (RobotAccountDataImpl) obj; - if (capabilities == null) { - if (other.capabilities != null) { - return false; - } - } else if (!capabilities.equals(other.capabilities)) { - return false; - } - if (consumerSecret == null) { - if (other.consumerSecret != null) { - return false; - } - } else if (!consumerSecret.equals(other.consumerSecret)) { - return false; - } - if (id == null) { - if (other.id != null) { - return false; - } - } else if (!id.equals(other.id)) { - return false; - } - if (isVerified != other.isVerified) { - return false; - } - if (url == null) { - if (other.url != null) { - return false; - } - } else if (!url.equals(other.url)) { - return false; - } - return true; - } - - @Override - public String toString() { - return "RobotAccountDataImp" + - "[id=" + id + - ",url=" + url + - ",consumerSecret=" + consumerSecret + - ",capabilities=" + capabilities + - ",isVerified=" + isVerified + "]"; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/attachment/AttachmentService.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/attachment/AttachmentService.java b/src/org/waveprotocol/box/server/attachment/AttachmentService.java deleted file mode 100644 index 163435f..0000000 --- a/src/org/waveprotocol/box/server/attachment/AttachmentService.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.attachment; - -import com.google.common.base.Preconditions; -import com.google.inject.Inject; -import java.awt.Color; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URLConnection; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.imageio.ImageIO; -import org.waveprotocol.box.attachment.AttachmentMetadata; -import org.waveprotocol.box.attachment.ImageMetadata; -import org.waveprotocol.box.attachment.impl.AttachmentMetadataImpl; -import org.waveprotocol.box.attachment.impl.ImageMetadataImpl; -import org.waveprotocol.box.server.persistence.AttachmentStore; -import org.waveprotocol.box.server.persistence.AttachmentStore.AttachmentData; -import org.waveprotocol.box.server.rpc.AttachmentServlet; -import org.waveprotocol.wave.media.model.AttachmentId; -import org.waveprotocol.wave.model.id.WaveletName; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.model.waveref.WaveRef; -import org.waveprotocol.wave.util.escapers.jvm.JavaWaverefEncoder; - -/** - * Serves storing and getting of attachments. - * - * @author [email protected] (A. Kaplanov) - */ -public class AttachmentService { - private static final Logger LOG = Logger.getLogger(AttachmentService.class.getName()); - - public static final String THUMBNAIL_MIME_TYPE = "image/jpeg"; - public static final String THUMBNAIL_FORMAT_NAME = "jpeg"; - - public static final int THUMBNAIL_PATTERN_WIDTH = 95; - public static final int THUMBNAIL_PATTERN_HEIGHT = 60; - - private static final int MAX_THUMBNAIL_WIDTH = 200; - private static final int MAX_THUMBNAIL_HEIGHT = 200; - - private final AttachmentStore store; - - @Inject - private AttachmentService(AttachmentStore store) { - this.store = store; - } - - public AttachmentMetadata getMetadata(AttachmentId attachmentId) throws IOException { - return store.getMetadata(attachmentId); - } - - public AttachmentData getAttachment(AttachmentId attachmentId) throws IOException { - return store.getAttachment(attachmentId); - } - - public AttachmentData getThumbnail(AttachmentId attachmentId) throws IOException { - return store.getThumbnail(attachmentId); - } - - public void storeAttachment(AttachmentId attachmentId, InputStream in, WaveletName waveletName, - String fileName, ParticipantId creator) throws IOException { - store.storeAttachment(attachmentId, in); - buildAndStoreMetadataWithThumbnail(attachmentId, waveletName, fileName, creator); - } - - public AttachmentMetadata buildAndStoreMetadataWithThumbnail(AttachmentId attachmentId, - WaveletName waveletName, String fileName, ParticipantId creator) throws IOException { - AttachmentData data = store.getAttachment(attachmentId); - if (data == null) { - throw new IOException("No such atachment " + attachmentId.serialise()); - } - AttachmentMetadata metadata = new AttachmentMetadataImpl(); - metadata.setAttachmentId(attachmentId.serialise()); - metadata.setAttachmentUrl(AttachmentServlet.ATTACHMENT_URL + "/" + attachmentId.serialise()); - metadata.setThumbnailUrl(AttachmentServlet.THUMBNAIL_URL + "/" + attachmentId.serialise()); - metadata.setWaveRef(waveletName2WaveRef(waveletName)); - metadata.setFileName(fileName); - String contentType = getMimeType(fileName); - metadata.setMimeType(contentType); - metadata.setSize(data.getSize()); - metadata.setCreator((creator != null) ? creator.getAddress() : ""); - BufferedImage image = null; - try { - image = ImageIO.read(data.getInputStream()); - } catch (IOException ex) { - LOG.log(Level.SEVERE, "Identifying attachment", ex); - } - if (image != null) { - ImageMetadata imageMetadata = new ImageMetadataImpl(); - imageMetadata.setWidth(image.getWidth()); - imageMetadata.setHeight(image.getHeight()); - metadata.setImageMetadata(imageMetadata); - try { - BufferedImage thumbnail = makeThumbnail(image); - storeThumbnail(attachmentId, thumbnail); - ImageMetadata thumbnailMetadata = new ImageMetadataImpl(); - thumbnailMetadata.setWidth(thumbnail.getWidth()); - thumbnailMetadata.setHeight(thumbnail.getHeight()); - metadata.setThumbnailMetadata(thumbnailMetadata); - } catch (IOException ex) { - LOG.log(Level.SEVERE, "Building attachment thumbnail", ex); - } - } else { - ImageMetadata thumbnailMetadata = new ImageMetadataImpl(); - thumbnailMetadata.setWidth(THUMBNAIL_PATTERN_WIDTH); - thumbnailMetadata.setHeight(THUMBNAIL_PATTERN_HEIGHT); - metadata.setThumbnailMetadata(thumbnailMetadata); - } - store.storeMetadata(attachmentId, metadata); - return metadata; - } - - private static BufferedImage makeThumbnail(BufferedImage image) { - int imageWidth = image.getWidth(); - int imageHeight = image.getHeight(); - Preconditions.checkState(imageHeight != 0); - Preconditions.checkState(imageWidth != 0); - int thumbnailWidth = imageWidth < MAX_THUMBNAIL_WIDTH ? imageWidth : MAX_THUMBNAIL_WIDTH; - int thumbnailHeight = imageHeight < MAX_THUMBNAIL_HEIGHT ? imageHeight : MAX_THUMBNAIL_HEIGHT; - if (imageWidth * thumbnailHeight < imageHeight * thumbnailWidth) { - thumbnailWidth = imageWidth * thumbnailHeight / imageHeight; - } else { - thumbnailHeight = imageHeight * thumbnailWidth / imageWidth; - } - BufferedImage thumbnail = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB); - Graphics2D g = thumbnail.createGraphics(); - try { - g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, - RenderingHints.VALUE_INTERPOLATION_BICUBIC); - g.setBackground(Color.BLACK); - g.clearRect(0, 0, thumbnailWidth, thumbnailHeight); - g.drawImage(image, 0, 0, thumbnailWidth, thumbnailHeight, null); - } finally { - g.dispose(); - } - return thumbnail; - } - - private void storeThumbnail(AttachmentId attachemntId, BufferedImage thumbnail) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ImageIO.write(thumbnail, THUMBNAIL_FORMAT_NAME, out); - store.storeThumbnail(attachemntId, new ByteArrayInputStream(out.toByteArray())); - } - - private static String waveletName2WaveRef(WaveletName waveletName) { - WaveRef waveRef = WaveRef.of(waveletName.waveId, waveletName.waveletId); - return JavaWaverefEncoder.encodeToUriPathSegment(waveRef); - } - - private static String getMimeType(String fileName) { - String mimeType = URLConnection.getFileNameMap().getContentTypeFor(fileName); - if (mimeType == null) { - return "application/octet-stream"; - } - return mimeType; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/AccountStoreHolder.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/AccountStoreHolder.java b/src/org/waveprotocol/box/server/authentication/AccountStoreHolder.java deleted file mode 100644 index 4c369c6..0000000 --- a/src/org/waveprotocol/box/server/authentication/AccountStoreHolder.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - -import com.google.common.base.Preconditions; - -import org.waveprotocol.box.server.persistence.AccountStore; - -/** - * This class holds a reference to a global AccountStore object. It is used in - * classes which are not instantiated by Guice, and for which the only way to - * access the account store is via static singletons. This is the case for JAAS - * configured login modules, like AccountStoreLoginModule. - * - * @author [email protected] (Joseph Gentle) - */ -public class AccountStoreHolder { - private static AccountStore store = null; - private static String defaultDomain = null; - - synchronized public static void init(AccountStore store, String defaultDomain) { - Preconditions.checkNotNull(store, "Account store cannot be null"); - Preconditions.checkNotNull(defaultDomain, "Default domain cannot be null"); - Preconditions.checkState(AccountStoreHolder.store == null, "Account store already set"); - AccountStoreHolder.store = store; - AccountStoreHolder.defaultDomain = defaultDomain.toLowerCase(); - } - - /** - * @return the non-null account store. - */ - public static AccountStore getAccountStore() { - Preconditions.checkNotNull(store, "Account store not set"); - return store; - } - - /** - * @return the non-null default domain - */ - public static String getDefaultDomain() { - Preconditions.checkNotNull(defaultDomain, "Default domain not set"); - return defaultDomain; - } - - /** Needed for testing. */ - public static void resetForTesting() { - store = null; - defaultDomain = null; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/AccountStoreLoginModule.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/AccountStoreLoginModule.java b/src/org/waveprotocol/box/server/authentication/AccountStoreLoginModule.java deleted file mode 100644 index e531397..0000000 --- a/src/org/waveprotocol/box/server/authentication/AccountStoreLoginModule.java +++ /dev/null @@ -1,170 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - -import com.google.common.base.Preconditions; - -import org.waveprotocol.box.server.account.AccountData; -import org.waveprotocol.box.server.persistence.AccountStore; -import org.waveprotocol.box.server.persistence.PersistenceException; -import org.waveprotocol.wave.model.wave.InvalidParticipantAddress; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.logging.Log; - -import java.util.Map; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; - -/** - * A Simple login module which does username & password authentication against - * users in a database. - * - * This code is based on the example here: - * http://java.sun.com/developer/technicalArticles/Security/jaasv2/ - * - * @author [email protected] (Joseph Gentle) - */ -public class AccountStoreLoginModule implements LoginModule { - private Subject subject; - private ParticipantPrincipal principal; - private CallbackHandler callbackHandler; - private AccountStore accountStore; - - private final Log LOG = Log.get(AccountStoreLoginModule.class); - - enum Status { - NOT, OK, COMMIT - } - - private Status status; - - @Override - public void initialize(Subject subject, CallbackHandler callbackHandler, - Map<String, ?> sharedState, Map<String, ?> options) { - Preconditions.checkNotNull(callbackHandler, "Callback handler null"); - - accountStore = AccountStoreHolder.getAccountStore(); - - status = Status.NOT; - this.subject = subject; - this.callbackHandler = callbackHandler; - } - - @Override - public boolean login() throws LoginException { - NameCallback nameCallback = new NameCallback("Username"); - PasswordCallback passwordCallback = new PasswordCallback("Password", false); - - Callback callbacks[] = new Callback[] {nameCallback, passwordCallback}; - - try { - callbackHandler.handle(callbacks); - } catch (java.io.IOException e) { - throw new LoginException(e.toString()); - } catch (UnsupportedCallbackException e) { - throw new LoginException("Error: " + e.getCallback().toString()); - } - - boolean success; - ParticipantId id = null; - - String address = nameCallback.getName(); - if (!address.contains(ParticipantId.DOMAIN_PREFIX)) { - address = address + ParticipantId.DOMAIN_PREFIX + AccountStoreHolder.getDefaultDomain(); - } - - try { - id = ParticipantId.of(address); - AccountData account = accountStore.getAccount(id); - char[] password = passwordCallback.getPassword(); - - if (account == null) { - // The user doesn't exist. Auth failed. - success = false; - } else if (!account.isHuman()) { - // The account is owned by a robot. Auth failed. - success = false; - } else if (password == null) { - // Null password provided by callback. We require a password (even an empty one). - success = false; - } else if (!account.asHuman().getPasswordDigest().verify(password)) { - // The supplied password doesn't match. Auth failed. - success = false; - } else { - success = true; - } - } catch (InvalidParticipantAddress e) { - // The supplied user address is invalid. Auth failed. - success = false; - } catch (PersistenceException e) { - LOG.severe("Failed to retreive account data for " + id, e); - throw new LoginException( - "An unexpected error occured while trying to retrieve account information!"); - } - - // The password is zeroed before it gets GC'ed for memory security. - passwordCallback.clearPassword(); - - if (success) { - principal = new ParticipantPrincipal(id); - status = Status.OK; - return true; - } else { - return false; - } - } - - @Override - public boolean commit() { - if (status == Status.NOT) { - return false; - } - if (subject == null) { - return false; - } - subject.getPrincipals().add(principal); - status = Status.COMMIT; - return true; - } - - @Override - public boolean abort() { - if ((subject != null) && (principal != null)) { - subject.getPrincipals().remove(principal); - } - principal = null; - status = Status.NOT; - return true; - } - - @Override - public boolean logout() { - subject.getPrincipals().remove(principal); - status = Status.NOT; - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/HttpRequestBasedCallbackHandler.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/HttpRequestBasedCallbackHandler.java b/src/org/waveprotocol/box/server/authentication/HttpRequestBasedCallbackHandler.java deleted file mode 100644 index cb99283..0000000 --- a/src/org/waveprotocol/box/server/authentication/HttpRequestBasedCallbackHandler.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - -import org.eclipse.jetty.util.MultiMap; - -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; - -/** - * A CallbackHandler which configures callbacks based on a set of parameters - * sent in an HTTP request. - * - * @author [email protected] (Joseph Gentle) - */ -public class HttpRequestBasedCallbackHandler implements CallbackHandler { - public static final String ADDRESS_FIELD = "address"; - public static final String PASSWORD_FIELD = "password"; - - private final MultiMap<String> parameters; - - public HttpRequestBasedCallbackHandler(MultiMap<String> parameters) { - this.parameters = parameters; - } - - @Override - public void handle(Callback[] callbacks) throws UnsupportedCallbackException { - for (Callback c : callbacks) { - if (c instanceof NameCallback) { - if (parameters.containsKey(ADDRESS_FIELD)) { - ((NameCallback) c).setName(parameters.getString(ADDRESS_FIELD)); - } - } else if (c instanceof PasswordCallback) { - if (parameters.containsKey(PASSWORD_FIELD)) { - String password = parameters.getString(PASSWORD_FIELD); - ((PasswordCallback) c).setPassword(password.toCharArray()); - } - } else { - throw new UnsupportedCallbackException(c); - } - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/ParticipantPrincipal.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/ParticipantPrincipal.java b/src/org/waveprotocol/box/server/authentication/ParticipantPrincipal.java deleted file mode 100644 index c0380bf..0000000 --- a/src/org/waveprotocol/box/server/authentication/ParticipantPrincipal.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - -import com.google.common.base.Preconditions; - -import org.waveprotocol.wave.model.wave.ParticipantId; - -import java.security.Principal; - -/** - * A principal for a wave user who logged in using the AccountStoreLoginModule. - * - * @author [email protected] (Joseph Gentle) - */ -public final class ParticipantPrincipal implements Principal { - private final ParticipantId id; - - /** - * Create a WavePrincipal for the given wave user. - * - * @param id The user's participant id. - */ - public ParticipantPrincipal(ParticipantId id) { - Preconditions.checkNotNull(id, "Participant id is null"); - this.id = id; - } - - @Override - public String getName() { - return id.getAddress(); - } - - @Override - public String toString() { - return "[Principal " + id + "]"; - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - ParticipantPrincipal other = (ParticipantPrincipal) obj; - return id.equals(other.id); - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/PasswordDigest.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/PasswordDigest.java b/src/org/waveprotocol/box/server/authentication/PasswordDigest.java deleted file mode 100644 index cdccca3..0000000 --- a/src/org/waveprotocol/box/server/authentication/PasswordDigest.java +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - - -import com.google.common.base.Preconditions; - -import org.waveprotocol.box.server.account.HumanAccountDataImpl; - -import java.io.Serializable; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.Arrays; - -/** - * A simple, secure, immutable password class. - * - * Passwords are stored using a salted SHA-384 digest. To persist a password - * object, use Java's serialization interface or save the salt and digest, and - * recreate the password object using Password.from(salt, digest). - * - * Character arrays are used instead of strings so the contents can be cleared - * before they are garbage collected. (Java's strings are immutable). Passwords - * should never be stored as strings at any intermediate stage. - * - * To serialize a digest to disk / database, either use Java's Serialization or - * store the byte arrays returned by both getSalt() and getDigest(). - * - * To deserialize a digest from disk / database, use {@code - * PasswordDigest.from(salt, digest);} - * - * @author [email protected] (Joseph Gentle) - */ -public class PasswordDigest implements Serializable { - public static final int DEFAULT_SALT_LENGTH = 16; - public static final int MINIMUM_SALT_LENGTH = 10; - public static final String DIGEST_HASHING_ALGORITHM = "SHA-512"; - - private final byte[] salt; - private final byte[] digest; - - // The random number generator is reused, as allocating the RNG each time we - // need one requires entropy, and is thus quite expensive. - private static ThreadLocal<SecureRandom> rng = new ThreadLocal<SecureRandom>() { - @Override - protected SecureRandom initialValue() { - return new SecureRandom(); - } - }; - - /** - * Create a password from the specified salt and digest. - */ - public static PasswordDigest from(byte[] salt, byte[] digest) { - return new PasswordDigest(salt.clone(), digest.clone()); - } - - /** - * Create a new password object using the password provided. - * - * Callers should clear the bytes in the password array when they're done - * with it. - */ - public PasswordDigest(char[] password) { - Preconditions.checkNotNull(password, "Password is null"); - - salt = generateSalt(); - digest = createPasswordDigest(password, salt); - } - - /** - * Helper for deserializing passwords. Use from(). - */ - private PasswordDigest(byte[] salt, byte[] digest) { - Preconditions.checkNotNull(salt, "Salt is null"); - Preconditions.checkNotNull(digest, "Digest is null"); - // A short salt makes passwords susceptible to rainbow tables. - Preconditions.checkArgument(salt.length >= 10, - "Salt length %d is too short. It must be at least %d to avoid rainbow table attacks.", - salt.length, MINIMUM_SALT_LENGTH); - // Note: We don't need to check the digest length, as if the digest is - // invalid, verify() will always fail anyway. - - this.salt = salt; - this.digest = digest; - } - - private static byte[] createPasswordDigest(char[] password, byte[] salt) { - MessageDigest hash; - try { - hash = MessageDigest.getInstance(DIGEST_HASHING_ALGORITHM); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException( - "Your java environment doesn't support the expected cryptographic hash function: " - + DIGEST_HASHING_ALGORITHM, e); - } - - hash.update(salt); - ByteBuffer passwordBytes = Charset.forName("UTF-8").encode(CharBuffer.wrap(password)); - hash.update(passwordBytes); - return hash.digest(); - } - - private static byte[] generateSalt(int length) { - byte[] new_salt = new byte[length]; - rng.get().nextBytes(new_salt); - return new_salt; - } - - private static byte[] generateSalt() { - return generateSalt(DEFAULT_SALT_LENGTH); - } - - /** - * Verify that the stored password matches the password provided. - * - * @param providedPassword Password to compare to the password stored - * @return true if the passwords match, false otherwise. - */ - public boolean verify(char[] providedPassword) { - Preconditions.checkNotNull(providedPassword, "Provided password is null"); - return digest != null && Arrays.equals(digest, createPasswordDigest(providedPassword, salt)); - } - - /** - * Get the salt bytes. - * - * @return A copy of the password's salt - */ - public byte[] getSalt() { - return salt.clone(); - } - - /** - * Get the password digest. - * - * @return A copy of the password's digest - */ - public byte[] getDigest() { - return digest.clone(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (!(obj instanceof PasswordDigest)) return false; - PasswordDigest other = (PasswordDigest) obj; - if (!Arrays.equals(this.salt, other.salt)) return false; - if (!Arrays.equals(this.digest, other.digest)) return false; - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/SessionManager.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/SessionManager.java b/src/org/waveprotocol/box/server/authentication/SessionManager.java deleted file mode 100644 index b8e00ae..0000000 --- a/src/org/waveprotocol/box/server/authentication/SessionManager.java +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - -import org.waveprotocol.box.server.account.AccountData; -import org.waveprotocol.wave.model.wave.ParticipantId; - -import javax.servlet.http.HttpSession; - - -/** - * Utility class for managing the session's authentication status. - * - * @author [email protected] (Joseph Gentle) - */ -public interface SessionManager { - static final String USER_FIELD = "user"; - - static final String SIGN_IN_URL = "/auth/signin"; - - - /** - * Get the participant id of the currently logged in user from the user's HTTP - * session. - * - * If the session is null, or if the user is not logged in, this function - * returns null. - * - * @param session The user's HTTP session, usually obtained from - * request.getSession(false); - * @return the user's participant id, or null if the user is not logged in. - */ - ParticipantId getLoggedInUser(HttpSession session); - - /** - * Get account data of the currently logged in user. - * - * If the session is null, or if the user is not logged in, this function - * returns null. - * - * @param session The user's HTTP session, usually obtained from - * request.getSession(false); - * @return the user's account data, or null if the user is not logged in. - */ - AccountData getLoggedInAccount(HttpSession session); - - /** - * Bind the user's participant id to the user's session. - * - * This records that a user has been logged in. - * - * @param session The user's HTTP session, usually obtained from - * request.getSession(true); - * @param id the user who has been logged in - */ - void setLoggedInUser(HttpSession session, ParticipantId id); - - /** - * Log the user out. - * - * If session is null, this function has no effect. - * - * @param session The user's HTTP session, obtainable from - * request.getSession(false); - */ - void logout(HttpSession session); - - /** - * Get the relative URL to redirect the user to the login page. - * - * @param redirect a url path to redirect the user back to once they have - * logged in, or null if the user should not be redirected after - * authenticating. - * @return a url containing the login page. - */ - String getLoginUrl(String redirect); - - /** - * Get a user's HttpSession from their session token. - * - * @param token the session token. Eg, "JSESSION=abcdef123567890" - * @return the user's HttpSession, or null if the token is invalid. - */ - HttpSession getSessionFromToken(String token); -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/7d8609e7/src/org/waveprotocol/box/server/authentication/SessionManagerImpl.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/authentication/SessionManagerImpl.java b/src/org/waveprotocol/box/server/authentication/SessionManagerImpl.java deleted file mode 100644 index c15e50a..0000000 --- a/src/org/waveprotocol/box/server/authentication/SessionManagerImpl.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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.waveprotocol.box.server.authentication; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; -import com.google.inject.Inject; - -import org.waveprotocol.box.server.account.AccountData; -import org.waveprotocol.box.server.persistence.AccountStore; -import org.waveprotocol.box.server.persistence.PersistenceException; -import org.waveprotocol.wave.model.wave.ParticipantId; -import org.waveprotocol.wave.util.escapers.PercentEscaper; -import org.waveprotocol.wave.util.logging.Log; - -import javax.servlet.http.HttpSession; - -/** - * Utility class for managing the session's authentication status. - * - * @author [email protected] (Joseph Gentle) - */ -public final class SessionManagerImpl implements SessionManager { - private static final String USER_FIELD = "user"; - - private final AccountStore accountStore; - private final org.eclipse.jetty.server.SessionManager jettySessionManager; - - private static final Log LOG = Log.get(SessionManagerImpl.class); - - @Inject - public SessionManagerImpl( - AccountStore accountStore, org.eclipse.jetty.server.SessionManager jettySessionManager) { - Preconditions.checkNotNull(accountStore, "Null account store"); - Preconditions.checkNotNull(jettySessionManager, "Null jetty session manager"); - this.accountStore = accountStore; - this.jettySessionManager = jettySessionManager; - } - - @Override - public ParticipantId getLoggedInUser(HttpSession session) { - if (session != null) { - return (ParticipantId) session.getAttribute(USER_FIELD); - } else { - return null; - } - } - - @Override - public AccountData getLoggedInAccount(HttpSession session) { - // Consider caching the account data in the session object. - ParticipantId user = getLoggedInUser(session); - if (user != null) { - try { - return accountStore.getAccount(user); - } catch (PersistenceException e) { - LOG.warning("Failed to retrieve account data for " + user, e); - return null; - } - } else { - return null; - } - } - - @Override - public void setLoggedInUser(HttpSession session, ParticipantId id) { - Preconditions.checkNotNull(session, "Session is null"); - Preconditions.checkNotNull(id, "Participant id is null"); - session.setAttribute(USER_FIELD, id); - } - - @Override - public void logout(HttpSession session) { - if (session != null) { - // This function should also remove any other bound fields in the session - // object. - session.removeAttribute(USER_FIELD); - } - } - - @Override - public String getLoginUrl(String redirect) { - if (Strings.isNullOrEmpty(redirect)) { - return SIGN_IN_URL; - } else { - PercentEscaper escaper = - new PercentEscaper(PercentEscaper.SAFEQUERYSTRINGCHARS_URLENCODER, false); - String queryStr = "?r=" + escaper.escape(redirect); - return SIGN_IN_URL + queryStr; - } - } - - @Override - public HttpSession getSessionFromToken(String token) { - Preconditions.checkNotNull(token); - return jettySessionManager.getHttpSession(token); - } -}
