/* * Copyright 2011 Google Inc. All Rights Reserved. * * 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.waveprotocol.box.waveimport.google.oauth; import com.google.common.base.Preconditions; import com.google.inject.servlet.RequestScoped; import org.waveprotocol.wave.model.wave.ParticipantId; import java.util.logging.Logger; import javax.annotation.Nullable; /** * Holds information about the user we are acting as. Many helper classes * receive a {@code UserContext} for making OAuth requests or for attributing * actions (for example, incoming deltas) to the current user. * * For each request, this starts out unintialized, since we have no uniform way * of identifying the user. Authentication filters like * {@link InteractiveAuthFilter} and {@link RpcAuthFilter} implement different * means of identifying the user and populate the {@code UserContext} * accordingly, including reading OAuth credentials from persistent storage. * * Servlets like {@link OAuthCallbackHandler} that need to manipulate * credentials in special ways populate the {@link UserContext} directly. * * Attempting to call a getter method while the corresponding information is not * present will result in an exception. This makes it easy to tell when * a servlet is not using the right authentication filter. * * This class is not thread-safe; if we ever use more than one thread for a * single request, we'll have to think about thread safety. * * This class is structurally similar to {@link AccountStore.Record} but plays a * very different role -- {@code UserContext} is mutable to allow authentication * filters (and other classes that handle login) to pass information about the * current user to other classes that need it, while {@code AccountStore.Record} * is an immutable in-memory representation of a record in {@link AccountStore}. * * @author ohler@google.com (Christian Ohler) */ @RequestScoped public class UserContext { @SuppressWarnings("unused") private static final Logger log = Logger.getLogger(UserContext.class.getName()); // At some point, we might want to refactor this to allow the auth filters to // perform retrieval of the OAuth credentials lazily -- many servlets don't // need credentials (or need them only in some cases), and the redundant // datastore read is undesirable. However, once we cache credentials in // memcache, we will merely be doing a redundant memcache lookup, which is // less of a problem. So implementing this laziness is not urgent. @Nullable private StableUserId userId = null; @Nullable private ParticipantId participantId = null; @Nullable private OAuthCredentials oAuthCredentials = null; public UserContext() { } public boolean hasUserId() { return userId != null; } public StableUserId getUserId() { Preconditions.checkState(hasUserId(), "No userId: %s", this); return userId; } public UserContext setUserId(@Nullable StableUserId userId) { this.userId = userId; return this; } public boolean hasParticipantId() { return participantId != null; } public ParticipantId getParticipantId() { Preconditions.checkState(hasParticipantId(), "No participantId: %s", this); return participantId; } public UserContext setParticipantId(@Nullable ParticipantId participantId) { this.participantId = participantId; return this; } public boolean hasOAuthCredentials() { return oAuthCredentials != null; } public OAuthCredentials getOAuthCredentials() { Preconditions.checkState(hasOAuthCredentials(), "No oAuthCredentials: %s", this); return oAuthCredentials; } public UserContext setOAuthCredentials(@Nullable OAuthCredentials oAuthCredentials) { this.oAuthCredentials = oAuthCredentials; return this; } @Override public String toString() { return "UserContext(" + userId + ", " + participantId + ", " + oAuthCredentials + ")"; } }