Package com.hp.hpl.jena.gvs.services.http.accountmanager

Source Code of com.hp.hpl.jena.gvs.services.http.accountmanager.AccountManager

/*
(c) Copyright 2005, 2006, Hewlett-Packard Development Company, LP
[See end of file]
$Id: AccountManager.java,v 1.3 2007/06/25 11:18:35 rebach Exp $
*/
package com.hp.hpl.jena.gvs.services.http.accountmanager;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wymiwyg.commons.util.Util;
import org.wymiwyg.commons.vocabulary.FOAF;
import org.wymiwyg.rdf.graphs.Graph;
import org.wymiwyg.rdf.graphs.NamedNode;
import org.wymiwyg.rdf.graphs.Node;
import org.wymiwyg.rdf.graphs.fgnodes.impl.InverseFunctionalPropertyNodeImpl;
import org.wymiwyg.rdf.graphs.impl.NamedNodeImpl;
import org.wymiwyg.rdf.graphs.impl.NodeImpl;
import org.wymiwyg.rdf.graphs.impl.PlainLiteralNodeImpl;
import org.wymiwyg.rdf.graphs.impl.PropertyNodeImpl;
import org.wymiwyg.rdf.graphs.impl.SimpleGraph;
import org.wymiwyg.rdf.graphs.impl.TripleImpl;
import org.wymiwyg.rdf.graphs.jenaimpl.JenaUtil;
import org.wymiwyg.wrhapi.HandlerException;
import org.wymiwyg.wrhapi.HeaderName;
import org.wymiwyg.wrhapi.MessageBody;
import org.wymiwyg.wrhapi.Request;
import org.wymiwyg.wrhapi.ResponseStatus;
import org.wymiwyg.wrhapi.util.Cookie;
import org.wymiwyg.wrhapi.util.MessageBody2Read;
import org.wymiwyg.wrhapi.util.parameterparser.KeyValuePair;
import org.wymiwyg.wrhapi.util.parameterparser.ParameterUtil;
import org.wymiwyg.wrhapi.util.parameterparser.ParameterValue;

import com.hp.hpl.jena.gvs.FCAGraph;
import com.hp.hpl.jena.gvs.GraphOverTime;
import com.hp.hpl.jena.gvs.Source;
import com.hp.hpl.jena.gvs.SourceStoreView;
import com.hp.hpl.jena.gvs.Store;
import com.hp.hpl.jena.gvs.StoreTransaction;
import com.hp.hpl.jena.gvs.impl.FCAGraphImpl;
import com.hp.hpl.jena.gvs.impl.SourceImpl;
import com.hp.hpl.jena.gvs.security.ACCOUNTMANAGER;
import com.hp.hpl.jena.gvs.security.AUTHORIZATION;
import com.hp.hpl.jena.gvs.services.http.graphserver.GraphHandler;
import com.hp.hpl.jena.gvs.services.http.graphserver.TypedResponse;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS;

/**
* @author reto
*
*/
public class AccountManager implements GraphHandler {

  /**
   * @author reto
   *
   */
  public static class LoginData {

    private String userName;

    private String passwordSha1;

    private String mboxSha1;

    /**
     * @param username
     * @param passwordSha1
     * @param mboxSha1
     */
    public LoginData(String userName, String passwordSha1, String mboxSha1) {
      this.userName = userName;
      this.passwordSha1 = passwordSha1;
      this.mboxSha1 = mboxSha1;
    }

    public String getMboxSha1() {
      return mboxSha1;
    }

    public String getPasswordSha1() {
      return passwordSha1;
    }

    public String getUserName() {
      return userName;
    }

  }

  /**
   * @author reto
   *
   */
  public static class Configuration {

    private String smtpHost = "localhost";

    private String fromAddress = "noreply@gvs";

    /**
     * @param store
     * @param configGOT
     * @param configuration
     *
     */
    public Configuration(Store store, GraphOverTime configGOT,
        NamedNode configuration) {

      Graph configGraph = configGOT.getGraph(new Date());
      Model configModel = JenaUtil.getModelFromGraph(configGraph);
      Resource httpConfigRes = configModel.createResource(configuration
          .getURIRef());
      Statement amConfigStmt = httpConfigRes
          .getProperty(WEBACCOUNTMANAGER.webAccountManagerConfiguration);
      if (amConfigStmt != null) {
        Resource amConfigRes = amConfigStmt.getResource();
        Statement smtpHostStmt = amConfigRes
            .getProperty(WEBACCOUNTMANAGER.smtpServer);
        if (smtpHostStmt != null) {
          smtpHost = smtpHostStmt.getString();
        }
        Statement fromAddressStmt = amConfigRes
            .getProperty(WEBACCOUNTMANAGER.fromAddress);
        if (fromAddressStmt != null) {
          fromAddress = fromAddressStmt.getString();
        }
      }
    }

    public String getSmtpHost() {
      return smtpHost;
    }

    public String getFromAddress() {
      return fromAddress;
    }

  }

  private static final Log log = LogFactory.getLog(AccountManager.class);

  private Store store;

  private LoginLinkSender loginLinkSender;

  private Configuration configuration;

  private Map<String, LoginData> verificationMap = new HashMap<String, LoginData>();

  private Source identity;

  private GraphOverTime configGOT;

  /**
   * @param store
   * @param configuration
   * @param trustedSources
   * @param identity
   *            the identity used to save the login-information
   */
  public AccountManager(Store store, Source identity,
      Set<Source> trustedSources, NamedNode configurationNode) {
    this.store = store;
    configGOT = store.getGraphOverTime(trustedSources);
    this.configuration = new Configuration(store, configGOT,
        configurationNode);
    this.loginLinkSender = new LoginLinkSender(configuration);
    this.identity = identity;
  }

  /*
   * (non-Javadoc)
   *
   * @see com.hp.hpl.jena.gvs.services.http.graphserver.GraphHandler#handle(org.wymiwyg.wrhapi.Request,
   *      com.hp.hpl.jena.gvs.services.http.graphserver.TypedResponse)
   */
  public void handle(Request request, TypedResponse<Graph> response)
      throws HandlerException {
    Map<String, String> parameterMap = new HashMap<String, String>();
    Iterator<KeyValuePair<ParameterValue>> parameters = ParameterUtil.getBodyPameters(request).iterator();
    while (parameters.hasNext()) {
      KeyValuePair<ParameterValue> currentPair = parameters.next();
      parameterMap.put(currentPair.getKey(), currentPair.getValue().toString());
    }
    String username = parameterMap.get("username");
    String password = parameterMap.get("password");
    if (parameterMap.containsKey("email")) {
      String email = parameterMap.get("email");
      String passwordSha1 = Util.sha1(password);
      String mboxSha1 = Util.sha1("mbox" + email);
      Resource user = getUserByUsername(username);
      if (user != null) {
        if (!user.hasProperty(FOAF.mbox_sha1sum, mboxSha1)) {
          throw new HandlerException(
              "user already exists with a differen email address");
        } else {
          log
              .info("Username/Email combination exist, will delete exitisting on confirmation");
        }
      }

      LoginData loginData = new LoginData(username, passwordSha1,
          mboxSha1);
      String verificationKey = Util.createRandomString(28);
      verificationMap.put(verificationKey, loginData);
      log.info("sending login link to " + email);
      loginLinkSender.sendLoginLink(email, getVerificationLink(request,
          verificationKey));
      response.setResponseStatus(ResponseStatus.MOVED_TEMPORARILY);
      response.setHeader(HeaderName.LOCATION,
          "/application/verification-sent");
    } else {
      String[] verificationParameters = request.getRequestURI()
          .getParameterValues("verification");
      if (verificationParameters != null) {
        if (verificationParameters.length == 1) {
          LoginData loginData = verificationMap
              .get(verificationParameters[0]);
          if (loginData == null) {
            throw new HandlerException(
                "Verification string not found, probably expired");
          }
          Graph graph = new SimpleGraph();
          addUser(loginData, graph, request);
          response
              .setDefaultStylesheet("/application/stylesheets/verification-result");
          response.setBody(graph);
          Resource user = getUserByUsernameInIdentityGOT(loginData.userName);
          FCAGraph revokeGraphTmp = null;
          if (user != null) {
            log
                .info("Username already exist, removing previous password");
            Model revokeModel = ModelFactory.createDefaultModel();
            revokeModel.add(user
                .listProperties(ACCOUNTMANAGER.passwordSha1));
            revokeModel.add(user.listProperties(FOAF.mbox_sha1sum));
            revokeModel.add(user
                .listProperties(ACCOUNTMANAGER.userName));
            revokeGraphTmp = new FCAGraphImpl(revokeModel);
            // store.revokeGraph(identity, new
            // FCAGraphImpl(revokeModel), now);
          }
          final FCAGraph revokeGraph = revokeGraphTmp;
          final FCAGraph assertGraph = new FCAGraphImpl(graph);
          // store.assertGraph(identity, new FCAGraphImpl(graph),
          // now);
          store.perform(identity, new StoreTransaction() {

            public void execute(SourceStoreView storeView) {
              if (revokeGraph != null)
                storeView.revokeGraph(revokeGraph);
              storeView.assertGraph(assertGraph);
            }

          });
        } else {
          throw new HandlerException(
              "Invalid request: needs exactly one verification-parameter");
        }
      } else {
        // login
        if (!loginValid(username, password)) {
          response.setResponseStatus(ResponseStatus.FORBIDDEN);
          response.setBody(new MessageBody2Read() {

            public ReadableByteChannel read() throws IOException {
              return Channels
                  .newChannel(new ByteArrayInputStream(
                      "LOGIN INVALID".getBytes()));
            }

          });
        }
        Cookie loginCookie = new Cookie("login", username + ":"
            + password);
        response.setHeader(HeaderName.SET_COOKIE, loginCookie
            .toString());
        response.setResponseStatus(ResponseStatus.MOVED_TEMPORARILY);
        response.setHeader(HeaderName.LOCATION,
            "/application/gvs-browser");
        // response.setBody((MessageBody)null);
      }
    }

  }

  /**
   * @param username
   * @param password
   * @return
   */
  private boolean loginValid(String username, String password) {
    Resource user = getUserByUsername(username);
    if (user == null) {
      return false;
    }
    return user.hasProperty(ACCOUNTMANAGER.passwordSha1, Util
        .sha1(password));
  }

  /**
   * @param username
   * @return
   */
  private Resource getUserByUsername(String username) {
    Graph graph = configGOT.getGraph(new Date());
    Model model = JenaUtil.getModelFromGraph(graph);
    ResIterator subjectIter = model.listSubjectsWithProperty(
        ACCOUNTMANAGER.userName, username);
    if (!subjectIter.hasNext()) {
      return null;
    }
    Resource subject = subjectIter.nextResource();
    if (subjectIter.hasNext()) {
      throw new RuntimeException("Username ambiguos");
    }
    return subject;
  }

  private Resource getUserByUsernameInIdentityGOT(String username) {
    Graph graph = store.getGraphOverTime(Collections.singleton(identity))
        .getGraph(new Date());
    Model model = JenaUtil.getModelFromGraph(graph);
    ResIterator subjectIter = model.listSubjectsWithProperty(
        ACCOUNTMANAGER.userName, username);
    if (!subjectIter.hasNext()) {
      return null;
    }
    Resource subject = subjectIter.nextResource();
    if (subjectIter.hasNext()) {
      throw new RuntimeException("Username ambiguos");
    }
    return subject;
  }

  /**
   * @param loginData
   * @param graph
   * @throws HandlerException
   */
  private void addUser(LoginData loginData, Graph graph, Request request)
      throws HandlerException {
    // TODO use an jenaModelWrapper (TBD)
    Node user = new NodeImpl();
    graph.add(new TripleImpl(user, new PropertyNodeImpl(RDF.type.getURI()),
        new NamedNodeImpl(FOAF.Agent.getURI())));
    graph.add(new TripleImpl(user, new InverseFunctionalPropertyNodeImpl(
        ACCOUNTMANAGER.userName.getURI()), new PlainLiteralNodeImpl(
        loginData.userName)));
    graph.add(new TripleImpl(user, new PropertyNodeImpl(
        ACCOUNTMANAGER.passwordSha1.getURI()),
        new PlainLiteralNodeImpl(loginData.passwordSha1)));
    graph.add(new TripleImpl(user, new InverseFunctionalPropertyNodeImpl(
        FOAF.mbox_sha1sum.getURI()), new PlainLiteralNodeImpl(
        loginData.mboxSha1)));
    graph.add(new TripleImpl(user, new PropertyNodeImpl(
        AUTHORIZATION.mayImpersonate.getURI()), new NamedNodeImpl(
        getUserSource(loginData.userName, request))));

  }

  /**
   * @param userName
   * @param request
   * @return
   * @throws HandlerException
   */
  private String getUserSource(String userName, Request request)
      throws HandlerException {
    StringBuffer resultBuffer = new StringBuffer();
    resultBuffer.append(request.getScheme().getStringRepresentation());
    resultBuffer.append("://");
    resultBuffer.append(request.getHeaderValues(HeaderName.HOST)[0]);

    resultBuffer.append("/user/");
    resultBuffer.append(userName);
    // resultBuffer.append('#');
    String result = resultBuffer.toString();
    Model creationModel = ModelFactory.createDefaultModel();
    creationModel.createResource(result).addProperty(RDFS.comment,
        "login Link sent at " + new Date());
    store.assertGraph(new SourceImpl(result), new FCAGraphImpl(
        creationModel));
    return result;
  }

  /**
   * @param request
   * @param verificationKey
   * @return
   * @throws HandlerException
   */
  private String getVerificationLink(Request request, String verificationKey)
      throws HandlerException {
    StringBuffer resultBuffer = new StringBuffer();
    resultBuffer.append(request.getScheme().getStringRepresentation());
    resultBuffer.append("://");
    resultBuffer.append(request.getHeaderValues(HeaderName.HOST)[0]);
    resultBuffer.append("/meta/account-manager?verification=");
    resultBuffer.append(verificationKey);
    return resultBuffer.toString();
  }

  private String getHost(Request request) throws HandlerException {
    String host;
    try {
      host = request.getHeaderValues(HeaderName.HOST)[0];
    } catch (ArrayIndexOutOfBoundsException e) {
      throw new HandlerException("No host header");
    }

    int colonPos = host.indexOf(':');

    if (colonPos != -1) {
      host = host.substring(0, colonPos);
    }

    return host;
  }
}

/*
* (c) Copyright 2005, 2006 Hewlett-Packard Development Company, LP All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
TOP

Related Classes of com.hp.hpl.jena.gvs.services.http.accountmanager.AccountManager

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.