Ejemplo n.º 1
0
  @Override
  public void appendData(final String data) throws DOMException {

    checkWriteAccess();

    // set content to concatenated text and data
    try {

      Services.command(securityContext, TransactionCommand.class)
          .execute(
              new StructrTransaction() {

                @Override
                public Object execute() throws FrameworkException {

                  String text = getProperty(content);
                  setProperty(content, text.concat(data));

                  return null;
                }
              });

    } catch (FrameworkException fex) {

      throw new DOMException(DOMException.INVALID_STATE_ERR, fex.toString());
    }
  }
Ejemplo n.º 2
0
  private void setOwner(final AbstractNode node, final AbstractNode user)
      throws FrameworkException {

    // Create outer transaction to bundle inner transactions
    Services.command(securityContext, TransactionCommand.class)
        .execute(
            new StructrTransaction() {

              @Override
              public Object execute() throws FrameworkException {

                DeleteRelationshipCommand delRel =
                    Services.command(securityContext, DeleteRelationshipCommand.class);

                // Remove any existing OWNS relationships
                for (AbstractRelationship s :
                    node.getRelationships(RelType.OWNS, Direction.INCOMING)) {

                  delRel.execute(s);
                }

                // Create new relationship to user and grant permissions to user or group
                Services.command(securityContext, CreateRelationshipCommand.class)
                    .execute(user, node, RelType.OWNS);

                return null;
              }
            });
  }
Ejemplo n.º 3
0
  @Override
  public void deleteData(final int offset, final int count) throws DOMException {

    checkWriteAccess();

    // finally, set content to concatenated left and right parts
    try {

      Services.command(securityContext, TransactionCommand.class)
          .execute(
              new StructrTransaction() {

                @Override
                public Object execute() throws FrameworkException {

                  String text = getProperty(content);

                  String leftPart = text.substring(0, offset);
                  String rightPart = text.substring(offset + count);

                  setProperty(content, leftPart.concat(rightPart));

                  return null;
                }
              });

    } catch (FrameworkException fex) {

      throw new DOMException(DOMException.INVALID_STATE_ERR, fex.toString());
    }
  }
Ejemplo n.º 4
0
  private void setPermission(
      final AbstractNode obj,
      final Principal principal,
      final String action,
      final String permission,
      final boolean rec)
      throws FrameworkException {

    Services.command(getWebSocket().getSecurityContext(), TransactionCommand.class)
        .execute(
            new StructrTransaction() {

              @Override
              public Object execute() throws FrameworkException {

                switch (action) {
                  case "grant":
                    principal.grant(Permission.valueOf(permission), obj);
                    break;
                  case "revoke":
                    principal.revoke(Permission.valueOf(permission), obj);
                    break;
                }

                return null;
              };
            });
  }
Ejemplo n.º 5
0
  public static void main(String[] args) {

    // TODO: handle parameters here?

    // start service layer using default configuration
    // augmented by local structr.conf
    Services.getInstance();
  }
  public void removeFromIndex(PropertyKey key) {

    for (Index<Relationship> index :
        Services.getInstance().getService(NodeService.class).getRelationshipIndices()) {

      synchronized (index) {
        index.remove(dbRelationship, key.dbName());
      }
    }
  }
  @Override
  public void removeFromIndex() {

    for (Index<Relationship> index :
        Services.getInstance().getService(NodeService.class).getRelationshipIndices()) {

      synchronized (index) {
        index.remove(dbRelationship);
      }
    }
  }
Ejemplo n.º 8
0
  @Override
  protected void setUp() throws Exception {

    init();

    securityContext = SecurityContext.getSuperUserInstance();
    createNodeCommand = Services.command(securityContext, CreateNodeCommand.class);
    createRelationshipCommand = Services.command(securityContext, CreateRelationshipCommand.class);
    deleteNodeCommand = Services.command(securityContext, DeleteNodeCommand.class);
    transactionCommand = Services.command(securityContext, TransactionCommand.class);
    graphDbCommand = Services.command(securityContext, GraphDatabaseCommand.class);
    findNodeCommand = Services.command(securityContext, FindNodeCommand.class);
  }
Ejemplo n.º 9
0
  private void setOwner(final List<AbstractNode> nodeList, final AbstractNode user)
      throws FrameworkException {

    // Create outer transaction to bundle inner transactions
    Services.command(securityContext, TransactionCommand.class)
        .execute(
            new StructrTransaction() {

              @Override
              public Object execute() throws FrameworkException {

                for (AbstractNode node : nodeList) {
                  setOwner(node, user);
                }

                return null;
              }
            });
  }
Ejemplo n.º 10
0
  @Override
  public boolean isValid(
      GraphObject object, PropertyKey<String> key, String value, ErrorBuffer errorBuffer) {

    if (key == null) {
      return false;
    }

    if (StringUtils.isBlank(value)) {
      errorBuffer.add(object.getType(), new EmptyPropertyToken(key));
      return false;
    }

    // FIXME: search should be case-sensitive!

    List<SearchAttribute> attrs = new LinkedList<SearchAttribute>();
    attrs.add(Search.andExactName(value));
    attrs.add(Search.andType(type));

    // just check for existance
    try {
      Result nodes = Services.command(securityContext, SearchNodeCommand.class).execute(attrs);
      if (nodes != null && !nodes.isEmpty()) {

        return true;

      } else {

        errorBuffer.add(object.getType(), new PropertyNotFoundToken(key, value));
        return false;
      }

    } catch (FrameworkException fex) {
      // handle error
    }

    return false;
  }
Ejemplo n.º 11
0
  @Override
  public Principal doLogin(
      final HttpServletRequest request, final String emailOrUsername, final String password)
      throws AuthenticationException, FrameworkException {

    final Principal user =
        AuthHelper.getPrincipalForPassword(Person.eMail, emailOrUsername, password);
    if (user != null) {

      final String allowLoginBeforeConfirmation =
          Services.getInstance()
              .getConfigurationValue(RegistrationResource.ALLOW_LOGIN_BEFORE_CONFIRMATION);
      if (user.getProperty(User.confirmationKey) != null
          && Boolean.FALSE.equals(Boolean.parseBoolean(allowLoginBeforeConfirmation))) {
        logger.log(Level.WARNING, "Login as {0} not allowed before confirmation.", user);
        throw new AuthenticationException(AuthHelper.STANDARD_ERROR_MSG);
      }

      AuthHelper.doLogin(request, user);
    }

    return user;
  }
Ejemplo n.º 12
0
  @Override
  public void afterCreation(SecurityContext securityContext) {

    try {

      final String filesPath = Services.getInstance().getConfigurationValue(Services.FILES_PATH);
      java.io.File fileOnDisk = new java.io.File(filesPath + "/" + getRelativeFilePath());

      if (fileOnDisk.exists()) {
        return;
      }

      fileOnDisk.getParentFile().mkdirs();

      try {

        fileOnDisk.createNewFile();

      } catch (IOException ex) {

        logger.log(Level.SEVERE, "Could not create file", ex);
        return;
      }

      setProperty(checksum, FileHelper.getChecksum(File.this));
      setProperty(version, 0);

      long fileSize = FileHelper.getSize(File.this);
      if (fileSize > 0) {
        setProperty(size, fileSize);
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, "Could not create file", ex);
    }
  }
Ejemplo n.º 13
0
  @Override
  public void insertData(final int offset, final String data) throws DOMException {

    checkWriteAccess();

    try {

      Services.command(securityContext, TransactionCommand.class)
          .execute(
              new StructrTransaction() {

                @Override
                public Object execute() throws FrameworkException {

                  String text = getProperty(content);

                  String leftPart = text.substring(0, offset);
                  String rightPart = text.substring(offset);

                  StringBuilder buf = new StringBuilder(text.length() + data.length() + 1);
                  buf.append(leftPart);
                  buf.append(data);
                  buf.append(rightPart);

                  // finally, set content to concatenated left, data and right parts
                  setProperty(content, buf.toString());

                  return null;
                }
              });

    } catch (FrameworkException fex) {

      throw new DOMException(DOMException.INVALID_STATE_ERR, fex.toString());
    }
  }
Ejemplo n.º 14
0
  public static void analyzeSchema() {

    final App app = StructrApp.getInstance();
    final FileBasedHashLongMap<NodeInfo> nodeIdMap =
        new FileBasedHashLongMap<>(userHome + File.separator + ".structrSchemaAnalyzer");
    final GraphDatabaseService graphDb = app.command(GraphDatabaseCommand.class).execute();
    final ConfigurationProvider configuration = Services.getInstance().getConfigurationProvider();
    final Set<NodeInfo> nodeTypes = new LinkedHashSet<>();
    final Set<RelationshipInfo> relationships = new LinkedHashSet<>();
    final Map<String, SchemaNode> schemaNodes = new LinkedHashMap<>();
    final Map<String, List<TypeInfo>> typeInfoTypeMap = new LinkedHashMap<>();
    final List<TypeInfo> reducedTypeInfos = new LinkedList<>();
    final List<TypeInfo> typeInfos = new LinkedList<>();
    Iterator<Relationship> relIterator = null;
    Iterator<Node> nodeIterator = null;

    logger.log(Level.INFO, "Fetching all nodes iterator..");

    try (final Tx tx = app.tx()) {

      nodeIterator =
          Iterables.filter(
                  new StructrAndSpatialPredicate(false, false, true),
                  GlobalGraphOperations.at(graphDb).getAllNodes())
              .iterator();
      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    logger.log(Level.INFO, "Starting to analyze nodes..");

    NodeServiceCommand.bulkGraphOperation(
        SecurityContext.getSuperUserInstance(),
        nodeIterator,
        100000,
        "Analyzing nodes",
        new BulkGraphOperation<Node>() {

          @Override
          public void handleGraphObject(final SecurityContext securityContext, final Node node)
              throws FrameworkException {

            final NodeInfo nodeInfo = new NodeInfo(node);

            // hashcode of nodeInfo is derived from its property and type signature!
            nodeTypes.add(nodeInfo);

            // add node ID to our new test datastructure
            nodeIdMap.add(nodeInfo, node.getId());
          }
        });

    logger.log(Level.INFO, "Identifying common base classes..");

    try (final Tx tx = app.tx(true, false, false)) {

      // nodeTypes now contains all existing node types and their property sets
      identifyCommonBaseClasses(app, nodeTypes, nodeIdMap, typeInfos);

      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    logger.log(Level.INFO, "Collecting type information..");

    try (final Tx tx = app.tx(true, false, false)) {

      // group type infos by type
      collectTypeInfos(typeInfos, typeInfoTypeMap);

      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    logger.log(Level.INFO, "Aggregating type information..");

    try (final Tx tx = app.tx(true, false, false)) {

      // reduce type infos with more than one type
      reduceTypeInfos(typeInfoTypeMap, reducedTypeInfos);

      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    logger.log(Level.INFO, "Identifying property sets..");
    try (final Tx tx = app.tx(true, false, false)) {

      // intersect property sets of type infos
      intersectPropertySets(reducedTypeInfos);

      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    logger.log(Level.INFO, "Sorting result..");
    try (final Tx tx = app.tx(false, false, false)) {

      // sort type infos
      Collections.sort(reducedTypeInfos, new HierarchyComparator(false));

      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    final Map<String, TypeInfo> reducedTypeInfoMap = new LinkedHashMap<>();

    for (final TypeInfo info : reducedTypeInfos) {

      final String type = info.getPrimaryType();

      // map TypeInfo to type for later use
      reducedTypeInfoMap.put(type, info);

      logger.log(Level.INFO, "Starting with setting of type and ID for type {0}", type);

      NodeServiceCommand.bulkGraphOperation(
          SecurityContext.getSuperUserInstance(),
          info.getNodeIds().iterator(),
          10000,
          "Setting type and ID",
          new BulkGraphOperation<Long>() {

            @Override
            public void handleGraphObject(SecurityContext securityContext, Long nodeId)
                throws FrameworkException {

              final Node node = graphDb.getNodeById(nodeId);

              node.setProperty(GraphObject.id.dbName(), NodeServiceCommand.getNextUuid());
              node.setProperty(GraphObject.type.dbName(), type);
            }
          });
    }

    logger.log(Level.INFO, "Fetching all relationships iterator..");

    try (final Tx tx = app.tx(false, false, false)) {

      relIterator =
          Iterables.filter(
                  new StructrAndSpatialPredicate(false, false, true),
                  GlobalGraphOperations.at(graphDb).getAllRelationships())
              .iterator();
      tx.success();

    } catch (FrameworkException fex) {
      fex.printStackTrace();
    }

    logger.log(Level.INFO, "Starting with analyzing relationships..");

    NodeServiceCommand.bulkGraphOperation(
        SecurityContext.getSuperUserInstance(),
        relIterator,
        10000,
        "Analyzing relationships",
        new BulkGraphOperation<Relationship>() {

          @Override
          public void handleGraphObject(SecurityContext securityContext, Relationship rel)
              throws FrameworkException {

            final Node startNode = rel.getStartNode();
            final Node endNode = rel.getEndNode();

            // make sure node has been successfully identified above
            if (startNode.hasProperty("type") && endNode.hasProperty("type")) {

              final String relationshipType = rel.getType().name();
              final String startNodeType = (String) startNode.getProperty("type");
              final String endNodeType = (String) endNode.getProperty("type");

              relationships.add(new RelationshipInfo(startNodeType, endNodeType, relationshipType));

              // create combined type on imported relationship
              if (startNodeType != null && endNodeType != null) {

                final String combinedType =
                    getCombinedType(startNodeType, relationshipType, endNodeType);

                logger.log(
                    Level.FINE,
                    "Combined relationship type {0} found for rel type {1}, start node type {2}, end node type {3}",
                    new Object[] {combinedType, relationshipType, startNodeType, endNodeType});

                rel.setProperty(GraphObject.type.dbName(), combinedType);
              }

              // create ID on imported relationship
              rel.setProperty(GraphObject.id.dbName(), NodeServiceCommand.getNextUuid());
            }
          }
        });

    logger.log(Level.INFO, "Grouping relationships..");

    // group relationships by type
    final Map<String, List<RelationshipInfo>> relTypeInfoMap = new LinkedHashMap<>();
    for (final RelationshipInfo relInfo : relationships) {

      // final String relType         = relInfo.getRelType();
      final String combinedType =
          getCombinedType(
              relInfo.getStartNodeType(), relInfo.getRelType(), relInfo.getEndNodeType());
      List<RelationshipInfo> infos = relTypeInfoMap.get(combinedType);

      if (infos == null) {

        infos = new LinkedList<>();
        relTypeInfoMap.put(combinedType, infos);
      }

      infos.add(relInfo);
    }

    logger.log(Level.INFO, "Aggregating relationship information..");

    final List<RelationshipInfo> reducedRelationshipInfos = new ArrayList<>();
    if ("true"
        .equals(
            Services.getInstance()
                .getConfigurationValue("importer.inheritancedetection", "true"))) {

      // reduce relationship infos into one
      for (final List<RelationshipInfo> infos : relTypeInfoMap.values()) {

        reducedRelationshipInfos.addAll(reduceNodeTypes(infos, reducedTypeInfoMap));
      }

    } else {

      reducedRelationshipInfos.addAll(relationships);
    }

    logger.log(Level.INFO, "Starting with schema node creation..");

    NodeServiceCommand.bulkGraphOperation(
        SecurityContext.getSuperUserInstance(),
        reducedTypeInfos.iterator(),
        100000,
        "Creating schema nodes",
        new BulkGraphOperation<TypeInfo>() {

          @Override
          public void handleGraphObject(SecurityContext securityContext, TypeInfo typeInfo)
              throws FrameworkException {

            final String type = typeInfo.getPrimaryType();
            if (!"ReferenceNode".equals(type)) {

              final Map<String, Class> props = typeInfo.getPropertySet();
              final PropertyMap propertyMap = new PropertyMap();

              // add properties
              for (final Map.Entry<String, Class> propertyEntry : props.entrySet()) {

                final String propertyName = propertyEntry.getKey();
                final Class propertyType = propertyEntry.getValue();

                // handle array types differently
                String propertyTypeName = propertyType.getSimpleName();
                if (propertyType.isArray()) {

                  // remove "[]" from the end and append "Array" to match the appropriate parser
                  propertyTypeName =
                      propertyTypeName.substring(0, propertyTypeName.length() - 2).concat("Array");
                }

                propertyMap.put(new StringProperty("_".concat(propertyName)), propertyTypeName);
              }

              // set node type which is in "name" property
              propertyMap.put(AbstractNode.name, type);

              // check if there is an existing Structr entity with the same type
              // and make the dynamic class extend the existing class if yes.
              final Class existingType = configuration.getNodeEntityClass(type);
              if (existingType != null) {

                propertyMap.put(SchemaNode.extendsClass, existingType.getName());

              } else if (!typeInfo.getOtherTypes().isEmpty()) {

                // only the first supertype is supported
                propertyMap.put(
                    SchemaNode.extendsClass, typeInfo.getSuperclass(reducedTypeInfoMap));
              }

              final SchemaNode existingNode =
                  app.nodeQuery(SchemaNode.class).andName(type).getFirst();
              if (existingNode != null) {

                for (final Entry<PropertyKey, Object> entry : propertyMap.entrySet()) {

                  existingNode.setProperty(entry.getKey(), entry.getValue());
                }

                schemaNodes.put(type, existingNode);

              } else {

                // create schema node
                schemaNodes.put(type, app.create(SchemaNode.class, propertyMap));
              }
            }
          }
        });

    logger.log(Level.INFO, "Starting with schema relationship creation..");

    NodeServiceCommand.bulkGraphOperation(
        SecurityContext.getSuperUserInstance(),
        reducedRelationshipInfos.iterator(),
        100000,
        "Creating schema relationships",
        new BulkGraphOperation<RelationshipInfo>() {

          @Override
          public void handleGraphObject(SecurityContext securityContext, RelationshipInfo template)
              throws FrameworkException {

            final SchemaNode startNode = schemaNodes.get(template.getStartNodeType());
            final SchemaNode endNode = schemaNodes.get(template.getEndNodeType());
            final String relationshipType = template.getRelType();
            final PropertyMap propertyMap = new PropertyMap();

            propertyMap.put(SchemaRelationshipNode.sourceId, startNode.getUuid());
            propertyMap.put(SchemaRelationshipNode.targetId, endNode.getUuid());
            propertyMap.put(SchemaRelationshipNode.relationshipType, relationshipType);

            app.create(SchemaRelationshipNode.class, propertyMap);
          }
        });

    logger.log(Level.INFO, "Starting with index rebuild..");

    // rebuild index
    app.command(BulkRebuildIndexCommand.class).execute(Collections.EMPTY_MAP);
  }
Ejemplo n.º 15
0
  @Override
  public void run() {

    final Services servicesInstance = Services.getInstance();

    // wait for service layer to be initialized
    while (!servicesInstance.isInitialized()) {
      try {
        Thread.sleep(1000);
      } catch (InterruptedException iex) {
      }
    }

    // sleep 5 seconds more
    try {
      Thread.sleep(5000);
    } catch (InterruptedException iex) {
    }

    while (doRun) {

      // sleep for some time
      try {
        Thread.sleep(GRANULARITY_UNIT.toMillis(GRANULARITY));
      } catch (InterruptedException iex) {
      }

      for (CronEntry entry : cronEntries) {

        if (entry.getDelayToNextExecutionInMillis() < GRANULARITY_UNIT.toMillis(GRANULARITY)) {

          final String taskClassName = entry.getName();
          final Class taskClass = instantiate(taskClassName);

          try {

            if (taskClass != null) {

              Task task = (Task) taskClass.newInstance();

              logger.debug("Starting task {}", taskClassName);
              StructrApp.getInstance().processTasks(task);

            } else {

              try (final Tx tx = StructrApp.getInstance().tx()) {

                // check for schema method with the given name
                Actions.call(taskClassName, Collections.EMPTY_MAP);

                tx.success();
              }
            }

          } catch (Throwable t) {
            logger.warn(
                "Exception while executing cron task {}: {}", taskClassName, t.getMessage());
          }
        }
      }
    }
  }
Ejemplo n.º 16
0
  @Override
  public Text splitText(int offset) throws DOMException {

    checkWriteAccess();

    String text = getProperty(content);

    if (text != null) {

      int len = text.length();

      if (offset < 0 || offset > len) {

        throw new DOMException(DOMException.INDEX_SIZE_ERR, INDEX_SIZE_ERR_MESSAGE);

      } else {

        final String firstPart = text.substring(0, offset);
        final String secondPart = text.substring(offset);

        final Document document = getOwnerDocument();
        final Node parent = getParentNode();

        if (document != null && parent != null) {

          try {

            return Services.command(securityContext, TransactionCommand.class)
                .execute(
                    new StructrTransaction<Text>() {

                      @Override
                      public Text execute() throws FrameworkException {

                        // first part goes into existing text element
                        setProperty(content, firstPart);

                        // second part goes into new text element
                        Text newNode = document.createTextNode(secondPart);

                        // make new node a child of old parent
                        parent.appendChild(newNode);

                        return newNode;
                      }
                    });

          } catch (FrameworkException fex) {

            throw new DOMException(DOMException.INVALID_STATE_ERR, fex.toString());
          }

        } else {

          throw new DOMException(DOMException.INVALID_STATE_ERR, CANNOT_SPLIT_TEXT_WITHOUT_PARENT);
        }
      }
    }

    throw new DOMException(DOMException.INDEX_SIZE_ERR, INDEX_SIZE_ERR_MESSAGE);
  }
Ejemplo n.º 17
0
  @Override
  protected void doGet(final HttpServletRequest request, final HttpServletResponse response) {

    final Authenticator auth = config.getAuthenticator();
    final SecurityContext securityContext;
    final App app;

    try {
      String path = request.getPathInfo();

      // check for registration (has its own tx because of write access
      if (checkRegistration(auth, request, response, path)) {

        return;
      }

      // isolate request authentication in a transaction
      try (final Tx tx = StructrApp.getInstance().tx()) {
        securityContext = auth.initializeAndExamineRequest(request, response);
        tx.success();
      }

      app = StructrApp.getInstance(securityContext);

      try (final Tx tx = app.tx()) {

        // Ensure access mode is frontend
        securityContext.setAccessMode(AccessMode.Frontend);

        request.setCharacterEncoding("UTF-8");

        // Important: Set character encoding before calling response.getWriter() !!, see Servlet
        // Spec 5.4
        response.setCharacterEncoding("UTF-8");

        boolean dontCache = false;

        logger.log(Level.FINE, "Path info {0}", path);

        // don't continue on redirects
        if (response.getStatus() == 302) {
          return;
        }

        Principal user = securityContext.getUser(false);
        if (user != null) {

          // Don't cache if a user is logged in
          dontCache = true;
        }

        final RenderContext renderContext =
            RenderContext.getInstance(request, response, getEffectiveLocale(request));

        renderContext.setResourceProvider(config.getResourceProvider());

        EditMode edit = renderContext.getEditMode(user);

        DOMNode rootElement = null;
        AbstractNode dataNode = null;

        String[] uriParts = PathHelper.getParts(path);
        if ((uriParts == null) || (uriParts.length == 0)) {

          // find a visible page
          rootElement = findIndexPage(securityContext);

          logger.log(Level.FINE, "No path supplied, trying to find index page");

        } else {

          if (rootElement == null) {

            rootElement = findPage(securityContext, request, path);

          } else {
            dontCache = true;
          }
        }

        if (rootElement == null) { // No page found

          // Look for a file
          File file = findFile(securityContext, request, path);
          if (file != null) {

            streamFile(securityContext, file, request, response, edit);
            return;
          }

          // store remaining path parts in request
          Matcher matcher = threadLocalUUIDMatcher.get();
          boolean requestUriContainsUuids = false;

          for (int i = 0; i < uriParts.length; i++) {

            request.setAttribute(uriParts[i], i);
            matcher.reset(uriParts[i]);

            // set to "true" if part matches UUID pattern
            requestUriContainsUuids |= matcher.matches();
          }

          if (!requestUriContainsUuids) {

            // Try to find a data node by name
            dataNode = findFirstNodeByName(securityContext, request, path);

          } else {

            dataNode = findNodeByUuid(securityContext, PathHelper.getName(path));
          }

          if (dataNode != null) {

            // Last path part matches a data node
            // Remove last path part and try again searching for a page
            // clear possible entry points
            request.removeAttribute(POSSIBLE_ENTRY_POINTS);

            rootElement =
                findPage(
                    securityContext,
                    request,
                    StringUtils.substringBeforeLast(path, PathHelper.PATH_SEP));

            renderContext.setDetailsDataObject(dataNode);

            // Start rendering on data node
            if (rootElement == null && dataNode instanceof DOMNode) {

              rootElement = ((DOMNode) dataNode);
            }
          }
        }

        // Still nothing found, do error handling
        if (rootElement == null) {

          // Check if security context has set an 401 status
          if (response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {

            try {

              UiAuthenticator.writeUnauthorized(response);

            } catch (IllegalStateException ise) {
            }

          } else {

            rootElement = notFound(response, securityContext);
          }
        }

        if (rootElement == null) {
          return;
        }

        if (EditMode.WIDGET.equals(edit) || dontCache) {

          setNoCacheHeaders(response);
        }

        if (!securityContext.isVisible(rootElement)) {

          rootElement = notFound(response, securityContext);
          if (rootElement == null) {
            return;
          }
        }

        if (securityContext.isVisible(rootElement)) {

          if (!EditMode.WIDGET.equals(edit)
              && !dontCache
              && notModifiedSince(request, response, rootElement, dontCache)) {

            ServletOutputStream out = response.getOutputStream();
            out.flush();
            // response.flushBuffer();
            out.close();

          } else {

            // prepare response
            response.setCharacterEncoding("UTF-8");

            String contentType = rootElement.getProperty(Page.contentType);

            if (contentType != null && contentType.equals("text/html")) {

              contentType = contentType.concat(";charset=UTF-8");
              response.setContentType(contentType);

            } else {

              // Default
              response.setContentType("text/html;charset=UTF-8");
            }

            response.setHeader("Strict-Transport-Security", "max-age=60");
            response.setHeader("X-Content-Type-Options", "nosniff");
            response.setHeader("X-Frame-Options", "SAMEORIGIN");
            response.setHeader("X-XSS-Protection", "1; mode=block");

            // async or not?
            boolean isAsync =
                HttpService.parseBoolean(
                    Services.getBaseConfiguration().getProperty(HttpService.ASYNC), true);
            if (isAsync) {

              final AsyncContext async = request.startAsync();
              final ServletOutputStream out = async.getResponse().getOutputStream();
              final AtomicBoolean finished = new AtomicBoolean(false);
              final DOMNode rootNode = rootElement;

              threadPool.submit(
                  new Runnable() {

                    @Override
                    public void run() {

                      try (final Tx tx = app.tx()) {

                        // final long start = System.currentTimeMillis();

                        // render
                        rootNode.render(securityContext, renderContext, 0);
                        finished.set(true);

                        // final long end = System.currentTimeMillis();
                        // System.out.println("Done in " + (end-start) + " ms");

                        tx.success();

                      } catch (Throwable t) {
                        t.printStackTrace();
                        final String errorMsg = t.getMessage();
                        try {
                          // response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                          response.sendError(
                              HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMsg);
                          finished.set(true);
                        } catch (IOException ex) {
                          ex.printStackTrace();
                        }
                      }
                    }
                  });

              // start output write listener
              out.setWriteListener(
                  new WriteListener() {

                    @Override
                    public void onWritePossible() throws IOException {

                      try {

                        final Queue<String> queue = renderContext.getBuffer().getQueue();
                        while (out.isReady()) {

                          String buffer = null;

                          synchronized (queue) {
                            buffer = queue.poll();
                          }

                          if (buffer != null) {

                            out.print(buffer);

                          } else {

                            if (finished.get()) {

                              async.complete();
                              response.setStatus(HttpServletResponse.SC_OK);

                              // prevent this block from being called again
                              break;
                            }

                            Thread.sleep(1);
                          }
                        }

                      } catch (Throwable t) {
                        t.printStackTrace();
                      }
                    }

                    @Override
                    public void onError(Throwable t) {
                      t.printStackTrace();
                    }
                  });

            } else {

              final StringRenderBuffer buffer = new StringRenderBuffer();
              renderContext.setBuffer(buffer);

              // render
              rootElement.render(securityContext, renderContext, 0);

              response.getOutputStream().write(buffer.getBuffer().toString().getBytes("utf-8"));
              response.getOutputStream().flush();
              response.getOutputStream().close();
            }
          }

        } else {

          notFound(response, securityContext);
        }

        tx.success();

      } catch (FrameworkException fex) {
        fex.printStackTrace();
        logger.log(Level.SEVERE, "Exception while processing request", fex);
      }

    } catch (IOException | FrameworkException t) {

      t.printStackTrace();
      logger.log(Level.SEVERE, "Exception while processing request", t);
      UiAuthenticator.writeInternalServerError(response);
    }
  }
Ejemplo n.º 18
0
  /**
   * Examine request and try to find a user.
   *
   * <p>First, check session id, then try external (OAuth) authentication, finally, check standard
   * login by credentials.
   *
   * @param request
   * @param response
   * @return security context
   * @throws FrameworkException
   */
  @Override
  public SecurityContext initializeAndExamineRequest(
      final HttpServletRequest request, final HttpServletResponse response)
      throws FrameworkException {

    SecurityContext securityContext;

    Principal user = checkSessionAuthentication(request);

    if (user == null) {

      user = checkExternalAuthentication(request, response);
    }

    if (user == null) {

      user = getUser(request, true);
    }

    if (user == null) {

      // If no user could be determined, assume frontend access
      securityContext = SecurityContext.getInstance(user, request, AccessMode.Frontend);

    } else {

      if (user instanceof SuperUser) {

        securityContext = SecurityContext.getSuperUserInstance(request);

      } else {

        securityContext = SecurityContext.getInstance(user, request, AccessMode.Backend);
      }
    }

    securityContext.setAuthenticator(this);

    // Check CORS settings (Cross-origin resource sharing, see
    // http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)
    final String origin = request.getHeader("Origin");
    if (!StringUtils.isBlank(origin)) {

      final Services services = Services.getInstance();

      response.setHeader("Access-Control-Allow-Origin", origin);

      // allow cross site resource sharing (read only)
      final String maxAge = services.getConfigurationValue(Services.ACCESS_CONTROL_MAX_AGE);
      if (StringUtils.isNotBlank(maxAge)) {
        response.setHeader("Access-Control-MaxAge", maxAge);
      }

      final String allowMethods =
          services.getConfigurationValue(Services.ACCESS_CONTROL_ALLOW_METHODS);
      if (StringUtils.isNotBlank(allowMethods)) {
        response.setHeader("Access-Control-Allow-Methods", allowMethods);
      }

      final String allowHeaders =
          services.getConfigurationValue(Services.ACCESS_CONTROL_ALLOW_HEADERS);
      if (StringUtils.isNotBlank(allowHeaders)) {
        response.setHeader("Access-Control-Allow-Headers", allowHeaders);
      }

      final String allowCredentials =
          services.getConfigurationValue(Services.ACCESS_CONTROL_ALLOW_CREDENTIALS);
      if (StringUtils.isNotBlank(allowCredentials)) {
        response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
      }

      final String exposeHeaders =
          services.getConfigurationValue(Services.ACCESS_CONTROL_EXPOSE_HEADERS);
      if (StringUtils.isNotBlank(exposeHeaders)) {
        response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
      }
    }

    examined = true;
    return securityContext;
  }
  @Override
  public Object execute(Object... parameters) throws FrameworkException {

    Command findRel = Services.command(securityContext, FindRelationshipCommand.class);

    for (Enum indexName : (RelationshipIndex[]) arguments.get("relationshipIndices")) {

      indices.put(indexName.name(), (Index<Relationship>) arguments.get(indexName.name()));
    }

    long id = 0;
    AbstractRelationship rel = null;
    String key = null;

    switch (parameters.length) {
      case 1:

        // index all properties of this relationship
        if (parameters[0] instanceof Long) {

          id = ((Long) parameters[0]).longValue();
          rel = (AbstractRelationship) findRel.execute(id);

          indexRelationship(rel);

        } else if (parameters[0] instanceof String) {

          id = Long.parseLong((String) parameters[0]);
          rel = (AbstractRelationship) findRel.execute(id);

          indexRelationship(rel);

        } else if (parameters[0] instanceof AbstractRelationship) {

          rel = (AbstractRelationship) parameters[0];

          indexRelationship(rel);

        } else if (parameters[0] instanceof List) {

          indexRelationships((List<AbstractRelationship>) parameters[0]);
        }

        break;

      case 2:

        // index a certain property
        if (parameters[0] instanceof Long) {

          id = ((Long) parameters[0]).longValue();
          rel = (AbstractRelationship) findRel.execute(id);

        } else if (parameters[0] instanceof String) {

          id = Long.parseLong((String) parameters[0]);
          rel = (AbstractRelationship) findRel.execute(id);

        } else if (parameters[0] instanceof AbstractRelationship) {

          rel = (AbstractRelationship) parameters[0];

          // id   = node.getId();

        }

        if (parameters[1] instanceof String) {

          key = (String) parameters[1];
        }

        if (rel == null) {

          logger.log(
              Level.SEVERE,
              "Wrong type of parameters for the index relationship command: {0}",
              parameters);
        }

        indexProperty(rel, key);

        break;

      default:
        logger.log(
            Level.SEVERE,
            "Wrong number of parameters for the index relationship command: {0}",
            parameters);

        return null;
    }

    return null;
  }
  @Override
  public Object execute(Object... parameters) throws FrameworkException {

    if (parameters == null || parameters.length < 2) {

      throw new UnsupportedArgumentError("Wrong number of arguments");
    }

    Long csvNodeId = null;
    AbstractNode sourceNode = null;
    Class targetClass = null;
    CsvFile csvFileNode = null;
    String filePath = null;
    Principal user = null;

    for (Object o : parameters) {

      if (o instanceof CsvFile) {

        csvFileNode = (CsvFile) o;
        filePath = Services.getFilesPath() + "/" + csvFileNode.getRelativeFilePath();
      }

      if (o instanceof Long) {

        csvNodeId = (Long) o;
        sourceNode =
            (AbstractNode)
                Services.command(securityContext, FindNodeCommand.class).execute(csvNodeId);

        if (sourceNode instanceof CsvFile) {

          csvFileNode = (CsvFile) sourceNode;
          filePath = Services.getFilesPath() + "/" + csvFileNode.getRelativeFilePath();
        }
      }

      if (o instanceof Class) {

        targetClass = (Class) o;
      }

      if (o instanceof Principal) {

        user = (Principal) o;
      }
    }

    try {

      // TODO: Implement auto-detection for field separator and quote characters
      CSVReader reader = new CSVReader(new FileReader(filePath), '|', '\"');

      // Read first line, these should be the column keys
      String[] keys = reader.readNext();

      // Get the fields of the target node
      Field[] fields = targetClass.getFields();

      // The field index stores the field name of a column
      Map<Integer, String> fieldIndex = new HashMap<Integer, String>();

      // Instantiate object
      AbstractNode o = (AbstractNode) targetClass.newInstance();
      int col = 0;

      // Match with fields
      for (String key : keys) {

        for (Field f : fields) {

          String fieldName = (String) f.get(o);

          if (fieldName.toUpperCase().equals(key.toUpperCase())) {

            fieldIndex.put(col, fieldName);
          }
        }

        col++;
      }

      for (Entry<Integer, String> entry : fieldIndex.entrySet()) {

        Integer i = entry.getKey();
        String v = entry.getValue();

        System.out.println("v: " + v + ", i: " + i);
      }

      //                      List<String[]> lines = reader.readAll();
      final Principal userCopy = user;
      final AbstractNode sourceNodeCopy = csvFileNode;
      final Command transactionCommand =
          Services.command(securityContext, TransactionCommand.class);
      final Command createNode = Services.command(securityContext, CreateNodeCommand.class);
      final Command createRel = Services.command(securityContext, CreateRelationshipCommand.class);
      final NodeList<AbstractNode> nodeListNode =
          (NodeList<AbstractNode>)
              transactionCommand.execute(
                  new StructrTransaction() {

                    @Override
                    public Object execute() throws FrameworkException {

                      // If the node list node doesn't exist, create one
                      NodeList<AbstractNode> result =
                          (NodeList)
                              createNode.execute(
                                  userCopy,
                                  new NodeAttribute(
                                      AbstractNode.Key.type.name(), NodeList.class.getSimpleName()),
                                  new NodeAttribute(
                                      AbstractNode.Key.name.name(),
                                      sourceNodeCopy.getName() + " List"));

                      createRel.execute(sourceNodeCopy, result, RelType.CONTAINS);

                      return result;
                    }
                  });
      final List<List<NodeAttribute>> creationList = new LinkedList<List<NodeAttribute>>();
      String targetClassName = targetClass.getSimpleName();
      String[] line = null;

      do {

        // read line, one at a time
        try {

          line = reader.readNext();

        } catch (Throwable t) {
        }

        if (line != null) {

          // create a new list for each item
          List<NodeAttribute> nodeAttributes = new LinkedList<NodeAttribute>();

          nodeAttributes.add(new NodeAttribute(AbstractNode.Key.type.name(), targetClassName));

          for (int i = 0; i < col; i++) {

            String csvValue = line[i];
            String key = fieldIndex.get(i);

            nodeAttributes.add(new NodeAttribute(key, csvValue));
          }

          // add node attributes to creation list
          creationList.add(nodeAttributes);
        }
      } while (line != null);

      reader.close();

      // everything in one transaction
      transactionCommand.execute(
          new StructrTransaction() {

            @Override
            public Object execute() throws FrameworkException {

              List<AbstractNode> nodesToAdd = new LinkedList<AbstractNode>();

              for (List<NodeAttribute> attrList : creationList) {

                nodesToAdd.add((AbstractNode) createNode.execute(attrList, false)); // don't index
              }

              // use bulk add
              nodeListNode.addAll(nodesToAdd);

              return (null);
            }
          });

      /*
       * final List<NodeAttribute> attrList = new LinkedList<NodeAttribute>();
       *
       * NodeAttribute typeAttr = new NodeAttribute(AbstractNode.Key.type.name(), targetClass.getSimpleName());
       * attrList.add(typeAttr);
       *
       * String[] line = null;
       *
       * do
       * {
       * try
       * {
       * line = reader.readNext();
       *
       * } catch(Throwable t)
       * {
       * line = null;
       * }
       *
       * if(line != null)
       * {
       * for(int i = 0; i < col; i++)
       * {
       *
       * String csvValue = line[i];
       * String key = fieldIndex.get(i);
       *
       * System.out.println("Creating attribute " + key + " = '" + csvValue + "'..");
       *
       * NodeAttribute attr = new NodeAttribute(key, csvValue);
       * attrList.add(attr);
       *
       * logger.log(Level.FINEST, "Created node attribute {0}={1}", new Object[]
       * {
       * attr.getKey(), attr.getValue()
       * });
       * }
       *
       * AbstractNode newNode = (AbstractNode)transactionCommand.execute(new StructrTransaction()
       * {
       * @Override
       * public Object execute() throws Throwable
       * {
       * Command createNode = Services.command(securityContext, CreateNodeCommand.class);
       *
       * // Create new node
       * AbstractNode newNode = (AbstractNode)createNode.execute(userCopy, attrList);
       * transactionCommand.setExitCode(createNode.getExitCode());
       * transactionCommand.setErrorMessage(createNode.getErrorMessage());
       * return newNode;
       * }
       * });
       *
       * nodeListNode.add(newNode);
       * logger.log(Level.INFO, "Node {0} added to node list", newNode.getId());
       * }
       *
       * } while(line != null);
       */
      return nodeListNode;
    } catch (Throwable t) {

      // TODO: use logger
      t.printStackTrace(System.out);
    }

    return null;
  }