// Copyright (C) 2010 The Android Open Source Project
//
// 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 com.google.gerrit.sshd;

import com.google.gerrit.reviewdb.AccountExternalId;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.sshd.SshScope.Context;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.session.ServerSession;

import java.net.SocketAddress;

/**
 * Authenticates by password through {@link AccountExternalId} entities.
 */
@Singleton
class DatabasePasswordAuth implements PasswordAuthenticator {
  private final AccountCache accountCache;
  private final SshLog log;
  private final IdentifiedUser.GenericFactory userFactory;

  @Inject
  DatabasePasswordAuth(final AccountCache ac, final SshLog l,
      final IdentifiedUser.GenericFactory uf) {
    accountCache = ac;
    log = l;
    userFactory = uf;
  }

  @Override
  public boolean authenticate(final String username, final String password,
      final ServerSession session) {
    final SshSession sd = session.getAttribute(SshSession.KEY);

    AccountState state = accountCache.getByUsername(username);
    if (state == null) {
      sd.authenticationError(username, "user-not-found");
      return false;
    }

    final String p = state.getPassword(username);
    if (p == null) {
      sd.authenticationError(username, "no-password");
      return false;
    }

    if (!p.equals(password)) {
      sd.authenticationError(username, "incorrect-password");
      return false;
    }

    if (sd.getCurrentUser() == null) {
      sd.authenticationSuccess(username, createUser(sd, state));

      // If this is the first time we've authenticated this
      // session, record a login event in the log and add
      // a close listener to record a logout event.
      //
      Context ctx = new Context(sd, null);
      Context old = SshScope.set(ctx);
      try {
        log.onLogin();
      } finally {
        SshScope.set(old);
      }

      session.getIoSession().getCloseFuture().addListener(
          new IoFutureListener<IoFuture>() {
            @Override
            public void operationComplete(IoFuture future) {
              final Context ctx = new Context(sd, null);
              final Context old = SshScope.set(ctx);
              try {
                log.onLogout();
              } finally {
                SshScope.set(old);
              }
            }
          });
    }

    return true;
  }

  private IdentifiedUser createUser(final SshSession sd,
      final AccountState state) {
    return userFactory.create(AccessPath.SSH_COMMAND,
        new Provider<SocketAddress>() {
          @Override
          public SocketAddress get() {
            return sd.getRemoteAddress();
          }
        }, state.getAccount().getId());
  }
}
