Package org.eclipse.orion.server.gerritfs

Source Code of org.eclipse.orion.server.gerritfs.GerritFileContents

/*******************************************************************************
* Copyright (c) 2010, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.orion.server.gerritfs;

import java.io.IOException;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gerrit.extensions.annotations.Export;
import com.google.gerrit.httpd.WebSession;
import com.google.gerrit.reviewdb.client.Project.NameKey;
import com.google.gerrit.server.AccessPath;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountException;
import com.google.gerrit.server.account.AccountManager;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

@Export("/contents/*")
@Singleton
public class GerritFileContents  extends HttpServlet {
  private final GitRepositoryManager repoManager;
  private final ProjectControl.Factory projControlFactory;
  private final Provider<WebSession> session;
  private final AccountCache accountCache;
  private final Config config;
  private final AccountManager accountManager;
 
  private static Logger log = LoggerFactory
      .getLogger(GerritFileContents.class);
  @Inject
  public GerritFileContents(final GitRepositoryManager repoManager, final ProjectControl.Factory project, Provider<WebSession> session, AccountCache accountCache,
        @GerritServerConfig Config config,
        final AccountManager accountManager) {
    this.repoManager = repoManager;
    this.projControlFactory = project;
    this.session = session;
    this.accountCache = accountCache;
    this.config = config;
    this.accountManager = accountManager;
  }
 
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    final ServletOutputStream out = resp.getOutputStream();
    handleAuth(req);
    try {
      String pathInfo = req.getPathInfo();
      Pattern pattern = Pattern.compile("/([^/]*)(?:/([^/]*)(?:/(.*))?)?");
      Matcher matcher = pattern.matcher(pathInfo);
      matcher.matches();
      String projectName = null;
      String refName = null;
      String filePath = null;
      if (matcher.groupCount() > 0) {
        projectName = matcher.group(1);
        refName = matcher.group(2);
        filePath = matcher.group(3);
        if (projectName == null || projectName.equals("")) {
          projectName = null;
        } else {
          projectName = java.net.URLDecoder.decode(projectName, "UTF-8");
        }
        if (refName == null || refName.equals("")) {
          refName = null;
        } else {
          refName = java.net.URLDecoder.decode(refName, "UTF-8");
        }
        if (filePath == null || filePath.equals("")) {
          filePath = null;
        } else {
          filePath = java.net.URLDecoder.decode(filePath, "UTF-8");
        }
      }
      if (projectName != null) {
        NameKey projName = NameKey.parse(projectName);
        ProjectControl control;
        try {
          control = projControlFactory.controlFor(projName);
          if (!control.isVisible()) {
            log.debug("Project not visible!");
            resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, "You need to be logged in to see private projects");
            return;
          }
        } catch (NoSuchProjectException e1) {
          resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "No such project exists.");
        }
      }
      if (projectName == null || refName == null || filePath == null) {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "You need to provide a projectName, refName and filePath.");
        return;
      } else {
        NameKey projName = NameKey.parse(projectName);
        Repository repo = repoManager.openRepository(projName);
        Ref head = repo.getRef(refName);
        RevWalk walk = new RevWalk(repo);
        RevCommit commit = walk.parseCommit(head.getObjectId());
        RevTree tree = commit.getTree();

        TreeWalk treeWalk = new TreeWalk(repo);
        treeWalk.addTree(tree);
        treeWalk.setRecursive(true);
        treeWalk.setFilter(PathFilter.create(filePath));
        if (!treeWalk.next()){
          throw new IllegalStateException("No file found");
        }
       
        ObjectId objId = treeWalk.getObjectId(0);
        ObjectLoader loader = repo.open(objId);
        resp.setHeader("Cache-Control", "no-cache");
        resp.setHeader("ETag", "\"" + tree.getId().getName() + "\"");
        resp.setContentType("application/octet-stream");
        loader.copyTo(out);
        walk.release();
        treeWalk.release();
      }
    } finally {
      out.close();
    }
  }

  private void handleAuth(HttpServletRequest req) {
    String username = req.getRemoteUser();
    if (username != null) {
       if (config.getBoolean("auth", "userNameToLowerCase", false)) {
            username = username.toLowerCase(Locale.US);
        }
      log.debug("User name: " + username);
       AccountState who = accountCache.getByUsername(username);
       log.debug("AccountState " + who);
      if (who == null && username.matches("^([a-zA-Z0-9][a-zA-Z0-9._-]*[a-zA-Z0-9]|[a-zA-Z0-9])$")) {
        log.debug("User is not registered with Gerrit. Register now."); // This approach assumes an auth type of HTTP_LDAP
        final AuthRequest areq = AuthRequest.forUser(username);
        try {
          accountManager.authenticate(areq);
          who = accountCache.getByUsername(username);
          if (who == null) {
            log.warn("Unable to register user \"" + username
                + "\". Continue as anonymous.");
          } else {
            log.debug("User registered.");
          }
        } catch (AccountException e) {
          log.warn("Exception registering user \"" + username
              + "\". Continue as anonymous.", e);
        }
      }
       if (who != null && who.getAccount().isActive()) {
         log.debug("Not anonymous user");
         WebSession ws = session.get();
         ws.setUserAccountId(who.getAccount().getId());
         ws.setAccessPathOk(AccessPath.REST_API, true);
        } else {
          log.debug("Anonymous user");
        }
    }
  }

}
TOP

Related Classes of org.eclipse.orion.server.gerritfs.GerritFileContents

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.