private HTMLNode getReceivedTrustCell(OwnIdentity truster, Identity trustee)
      throws DuplicateTrustException {

    String trustValue = "";
    String trustComment = "";
    Trust trust;

    try {
      trust = mWebOfTrust.getTrust(truster, trustee);
      trustValue = String.valueOf(trust.getValue());
      trustComment = trust.getComment();
    } catch (NotTrustedException e) {
    }

    HTMLNode cell = new HTMLNode("td");
    if (trustValue.length() > 0) {
      cell.addAttribute(
          "style",
          "background-color:"
              + KnownIdentitiesPage.getTrustColor(Integer.parseInt(trustValue))
              + ";");
    }

    // Trust value input field
    cell.addChild(
        "input",
        new String[] {"type", "name", "size", "maxlength", "value"},
        new String[] {"text", "Value" + trustee.getID(), "4", "4", trustValue});

    // Trust comment input field
    cell.addChild(
        "input",
        new String[] {"type", "name", "size", "maxlength", "value"},
        new String[] {
          "text",
          "Comment" + trustee.getID(),
          "50",
          Integer.toString(Trust.MAX_TRUST_COMMENT_LENGTH),
          trustComment
        });

    return cell;
  }
Esempio n. 2
0
  /** {@inheritDoc} */
  @Override
  public Response handleRequest(FreenetRequest request, Response response) throws IOException {
    String redirectTarget = getRedirectTarget(request);
    if (redirectTarget != null) {
      return new RedirectResponse(redirectTarget);
    }

    if (isFullAccessOnly() && !request.getToadletContext().isAllowedFullAccess()) {
      return response
          .setStatusCode(401)
          .setStatusText("Not authorized")
          .setContentType("text/html");
    }
    ToadletContext toadletContext = request.getToadletContext();
    if (request.getMethod() == Method.POST) {
      /* require form password. */
      String formPassword = request.getHttpRequest().getPartAsStringFailsafe("formPassword", 32);
      if (!formPassword.equals(toadletContext.getContainer().getFormPassword())) {
        return new RedirectResponse(invalidFormPasswordRedirectTarget);
      }
    }
    PageMaker pageMaker = toadletContext.getPageMaker();
    PageNode pageNode = pageMaker.getPageNode(getPageTitle(request), toadletContext);
    for (String styleSheet : getStyleSheets()) {
      pageNode.addCustomStyleSheet(styleSheet);
    }
    for (Map<String, String> linkNodeParameters : getAdditionalLinkNodes(request)) {
      HTMLNode linkNode = pageNode.headNode.addChild("link");
      for (Entry<String, String> parameter : linkNodeParameters.entrySet()) {
        linkNode.addAttribute(parameter.getKey(), parameter.getValue());
      }
    }
    String shortcutIcon = getShortcutIcon();
    if (shortcutIcon != null) {
      pageNode.addForwardLink("icon", shortcutIcon);
    }

    TemplateContext templateContext = templateContextFactory.createTemplateContext();
    templateContext.mergeContext(template.getInitialContext());
    try {
      long start = System.nanoTime();
      processTemplate(request, templateContext);
      long finish = System.nanoTime();
      logger.log(
          Level.FINEST, "Template was rendered in " + ((finish - start) / 1000) / 1000.0 + "ms.");
    } catch (RedirectException re1) {
      return new RedirectResponse(re1.getTarget());
    }

    StringWriter stringWriter = new StringWriter();
    template.render(templateContext, stringWriter);
    pageNode.content.addChild("%", stringWriter.toString());

    postProcess(request, templateContext);

    return response
        .setStatusCode(200)
        .setStatusText("OK")
        .setContentType("text/html")
        .write(pageNode.outer.generate());
  }
  /** Makes the list of Identities known by the tree owner. */
  private void makeKnownIdentitiesList() {

    String nickFilter = mRequest.getPartAsStringFailsafe("nickfilter", 100).trim();
    String sortBy =
        mRequest.isPartSet("sortby")
            ? mRequest.getPartAsStringFailsafe("sortby", 100).trim()
            : "Nickname";
    String sortType =
        mRequest.isPartSet("sorttype")
            ? mRequest.getPartAsStringFailsafe("sorttype", 100).trim()
            : "Ascending";

    int page =
        mRequest.isPartSet("page")
            ? Integer.parseInt(
                mRequest.getPartAsStringFailsafe(
                    "page", Integer.toString(Integer.MAX_VALUE).length()))
            : 0;
    page = page - 1; // What we get passed is the user-friendly page number counting from 1, not 0.
    page = Math.max(0, page); // In case no page part was set, it would be -1

    HTMLNode knownIdentitiesBox =
        addContentBox(l10n().getString("KnownIdentitiesPage.KnownIdentities.Header"));
    knownIdentitiesBox =
        pr.addFormChild(knownIdentitiesBox, uri.toString(), "Filters").addChild("p");
    knownIdentitiesBox.addChild(
        "input",
        new String[] {"type", "name", "value"},
        new String[] {"hidden", "page", Integer.toString(page + 1)});

    InfoboxNode filtersBoxNode =
        getContentBox(l10n().getString("KnownIdentitiesPage.FiltersAndSorting.Header"));

    { // Filters box
      knownIdentitiesBox.addChild(filtersBoxNode.outer);
      HTMLNode filtersBox = filtersBoxNode.content;
      filtersBox.addChild(
          "#",
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.ShowOnlyNicksContaining")
              + " : ");
      filtersBox.addChild(
          "input",
          new String[] {"type", "size", "name", "value"},
          new String[] {"text", "15", "nickfilter", nickFilter});

      filtersBox.addChild(
          "#",
          " " + l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy") + " : ");
      HTMLNode option =
          filtersBox.addChild(
              "select", new String[] {"name", "id"}, new String[] {"sortby", "sortby"});
      TreeMap<String, String> options = new TreeMap<String, String>();
      options.put(
          SortBy.Edition.toString(),
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.Edition"));
      options.put(
          SortBy.Nickname.toString(),
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.Nickname"));
      options.put(
          SortBy.Score.toString(),
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.Score"));
      options.put(
          SortBy.LocalTrust.toString(),
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.LocalTrust"));
      for (String e : options.keySet()) {
        HTMLNode newOption = option.addChild("option", "value", e, options.get(e));
        if (e.equals(sortBy)) {
          newOption.addAttribute("selected", "selected");
        }
      }

      option =
          filtersBox.addChild(
              "select", new String[] {"name", "id"}, new String[] {"sorttype", "sorttype"});
      options = new TreeMap<String, String>();
      options.put(
          "Ascending",
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.Ascending"));
      options.put(
          "Descending",
          l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.Descending"));
      for (String e : options.keySet()) {
        HTMLNode newOption = option.addChild("option", "value", e, options.get(e));
        if (e.equals(sortType)) {
          newOption.addAttribute("selected", "selected");
        }
      }

      filtersBox.addChild(
          "input",
          new String[] {"type", "value"},
          new String[] {
            "submit",
            l10n().getString("KnownIdentitiesPage.FiltersAndSorting.SortIdentitiesBy.SubmitButton")
          });
    }

    // Display the list of known identities
    HTMLNode identitiesTable = knownIdentitiesBox.addChild("table", "border", "0");
    identitiesTable.addChild(getKnownIdentitiesListTableHeader());

    WebOfTrust.SortOrder sortInstruction = WebOfTrust.SortOrder.valueOf("By" + sortBy + sortType);

    synchronized (mWebOfTrust) {
      long currentTime = CurrentTimeUTC.getInMillis();
      int indexOfFirstIdentity = page * IDENTITIES_PER_PAGE;

      // Re-query it instead of using mLoggedInOwnIdentity because mLoggedInOwnIdentity is a
      // clone() and thus will not work with database queries on the WebOfTrust.
      // TODO: Performance: This can be removed once the TODO at
      // WebPageImpl.getLoggedInOwnIdentityFromHTTPSession() of not cloning the
      // OwnIdentity has been been resolved.
      final OwnIdentity ownId;
      try {
        ownId = mWebOfTrust.getOwnIdentityByID(mLoggedInOwnIdentity.getID());
      } catch (UnknownIdentityException e) {
        new ErrorPage(mToadlet, mRequest, mContext, e).addToPage(this);
        return;
      }

      ObjectSet<Identity> allIdentities =
          mWebOfTrust.getAllIdentitiesFilteredAndSorted(ownId, nickFilter, sortInstruction);

      Iterator<Identity> identities;
      try {
        identities = allIdentities.listIterator(indexOfFirstIdentity);
      } catch (IndexOutOfBoundsException e) {
        // The user supplied a higher page index than there are pages. This can happen when the
        // user changes the search filters while not being on the first page.
        // We fall back to displaying the last page.
        // Notice: We intentionally do not prevent listIterator() from throwing by checking
        // the index for validity before calling listIterator(). This is because we would need
        // to call allIdentities.size() to check the index. This would force the database to
        // compute the full result set even though we only need the results up to the current
        // page if we are not on the last page.
        page = getPageCount(allIdentities.size()) - 1;
        indexOfFirstIdentity = page * IDENTITIES_PER_PAGE;

        // TODO: Performance: Don't re-query this from the database once the issue which caused
        // this workaround is fixed: https://bugs.freenetproject.org/view.php?id=6646
        allIdentities =
            mWebOfTrust.getAllIdentitiesFilteredAndSorted(ownId, nickFilter, sortInstruction);

        identities = allIdentities.listIterator(indexOfFirstIdentity);
      }

      for (int displayed = 0;
          displayed < IDENTITIES_PER_PAGE && identities.hasNext();
          ++displayed) {
        final Identity id = identities.next();

        if (id == ownId) continue;

        HTMLNode row = identitiesTable.addChild("tr");

        // NickName
        HTMLNode nameLink =
            row.addChild(
                    "td",
                    new String[] {"title", "style"},
                    new String[] {id.getRequestURI().toString(), "cursor: help;"})
                .addChild("a", "href", IdentityPage.getURI(mWebInterface, id.getID()).toString());

        String nickName = id.getNickname();

        if (nickName != null) {
          nameLink.addChild("#", nickName + "@" + id.getID().substring(0, 5) + "...");
        } else
          nameLink
              .addChild("span", "class", "alert-error")
              .addChild(
                  "#",
                  l10n()
                      .getString(
                          "KnownIdentitiesPage.KnownIdentities.Table.NicknameNotDownloadedYet"));

        // Added date
        row.addChild(
            "td",
            CommonWebUtils.formatTimeDelta(currentTime - id.getAddedDate().getTime(), l10n()));

        // Last fetched date
        Date lastFetched = id.getLastFetchedDate();
        if (!lastFetched.equals(new Date(0)))
          row.addChild(
              "td", CommonWebUtils.formatTimeDelta(currentTime - lastFetched.getTime(), l10n()));
        else row.addChild("td", l10n().getString("Common.Never"));

        // Publish TrustList
        row.addChild(
            "td",
            new String[] {"align"},
            new String[] {"center"},
            id.doesPublishTrustList()
                ? l10n().getString("Common.Yes")
                : l10n().getString("Common.No"));

        // Score
        try {
          final Score score = mWebOfTrust.getScore(ownId, id);
          final int scoreValue = score.getScore();
          final int rank = score.getRank();

          row.addChild(
              "td",
              new String[] {"align", "style"},
              new String[] {
                "center", "background-color:" + KnownIdentitiesPage.getTrustColor(scoreValue) + ";"
              },
              Integer.toString(scoreValue)
                  + " ("
                  + (rank != Integer.MAX_VALUE
                      ? rank
                      : l10n().getString("KnownIdentitiesPage.KnownIdentities.Table.InfiniteRank"))
                  + ")");
        } catch (NotInTrustTreeException e) {
          // This only happen with identities added manually by the user
          row.addChild("td", l10n().getString("KnownIdentitiesPage.KnownIdentities.Table.NoScore"));
        }

        // Own Trust
        row.addChild(getReceivedTrustCell(ownId, id));

        // Checkbox
        row.addChild(getSetTrustCell(id));

        // Nb Trusters
        // TODO: Do a direct link to the received-trusts part of the linked page
        HTMLNode trustersCell = row.addChild("td", new String[] {"align"}, new String[] {"center"});
        trustersCell.addChild(
            new HTMLNode(
                "a",
                "href",
                IdentityPage.getURI(mWebInterface, id.getID()).toString(),
                Long.toString(mWebOfTrust.getReceivedTrusts(id).size())));

        // Nb Trustees
        // TODO: Do a direct link to the given-trusts part of the linked page
        HTMLNode trusteesCell = row.addChild("td", new String[] {"align"}, new String[] {"center"});
        trusteesCell.addChild(
            new HTMLNode(
                "a",
                "href",
                IdentityPage.getURI(mWebInterface, id.getID()).toString(),
                Long.toString(mWebOfTrust.getGivenTrusts(id).size())));

        // TODO: Show in advanced mode only once someone finally fixes the "Switch to advanced mode"
        // link on FProxy to work on ALL pages.

        row.addChild("td", "align", "center", Long.toString(id.getEdition()));

        row.addChild("td", "align", "center", Long.toString(id.getLatestEditionHint()));
      }
      identitiesTable.addChild(getKnownIdentitiesListTableHeader());
      knownIdentitiesBox.addChild(getKnownIdentitiesListPageLinks(page, allIdentities.size()));
    }
  }
  public void handleMethodGET(URI uri, HTTPRequest req, ToadletContext ctx)
      throws ToadletContextClosedException, IOException {

    if (!ctx.checkFullAccess(this)) return;

    boolean advancedModeEnabled = ctx.isAdvancedModeEnabled();

    PageNode page =
        ctx.getPageMaker()
            .getPageNode(NodeL10n.getBase().getString("ConfigToadlet.fullTitle"), ctx);
    HTMLNode pageNode = page.outer;
    HTMLNode contentNode = page.content;

    contentNode.addChild(ctx.getAlertManager().createSummary());

    HTMLNode infobox = contentNode.addChild("div", "class", "infobox infobox-normal");
    infobox.addChild("div", "class", "infobox-header", l10n("title"));
    HTMLNode configNode = infobox.addChild("div", "class", "infobox-content");
    HTMLNode formNode = ctx.addFormChild(configNode, path(), "configForm");

    // Invisible apply button at the top so that an enter keypress will
    // apply settings instead of
    // going to a directory browser if present.
    formNode.addChild(
        "input",
        new String[] {"type", "value", "class"},
        new String[] {"submit", l10n("apply"), "invisible"});

    /*
     * Special case: present an option for the wrapper's maximum memory
     * under Core configuration, provided the maximum memory property is
     * defined. (the wrapper is being used)
     */
    if (subConfig.getPrefix().equals("node") && WrapperConfig.canChangeProperties()) {
      String configName = "wrapper.java.maxmemory";
      String curValue = WrapperConfig.getWrapperProperty(configName);
      // If persisted from directory browser, override. This is a POST
      // HTTPRequest.
      if (req.isPartSet(configName)) {
        curValue = req.getPartAsStringFailsafe(configName, MAX_PARAM_VALUE_SIZE);
      }
      if (curValue != null) {
        formNode.addChild("div", "class", "configprefix", l10n("wrapper"));
        HTMLNode list = formNode.addChild("ul", "class", "config");
        HTMLNode item = list.addChild("li", "class", OptionType.TEXT.cssClass);
        // FIXME how to get the real default???
        String defaultValue = "256";
        item.addChild(
                "span",
                new String[] {"class", "title", "style"},
                new String[] {
                  "configshortdesc",
                  NodeL10n.getBase()
                      .getString(
                          "ConfigToadlet.defaultIs",
                          new String[] {"default"},
                          new String[] {defaultValue}),
                  "cursor: help;"
                })
            .addChild(NodeL10n.getBase().getHTMLNode("WrapperConfig." + configName + ".short"));
        item.addChild("span", "class", "config")
            .addChild(
                "input",
                new String[] {"type", "class", "name", "value"},
                new String[] {"text", "config", configName, curValue});
        item.addChild("span", "class", "configlongdesc")
            .addChild(NodeL10n.getBase().getHTMLNode("WrapperConfig." + configName + ".long"));
      }
    }

    short displayedConfigElements = 0;
    HTMLNode configGroupUlNode = new HTMLNode("ul", "class", "config");

    String overriddenOption = null;
    String overriddenValue = null;

    // A value changed by the directory selector takes precedence.
    if (req.isPartSet("select-for") && req.isPartSet(LocalFileBrowserToadlet.selectDir)) {
      overriddenOption = req.getPartAsStringFailsafe("select-for", MAX_PARAM_VALUE_SIZE);
      overriddenValue = req.getPartAsStringFailsafe("filename", MAX_PARAM_VALUE_SIZE);
    }

    /*
     * Present all other options for this subconfig.
     */
    for (Option<?> o : subConfig.getOptions()) {
      if (!((!advancedModeEnabled) && o.isExpert())) {
        displayedConfigElements++;
        String configName = o.getName();
        String fullName = subConfig.getPrefix() + '.' + configName;
        String value = o.getValueDisplayString();

        if (value == null) {
          Logger.error(this, fullName + "has returned null from config!);");
          continue;
        }

        ConfigCallback<?> callback = o.getCallback();

        final OptionType optionType;
        if (callback instanceof EnumerableOptionCallback) {
          optionType = OptionType.DROP_DOWN;
        } else if (callback instanceof BooleanCallback) {
          optionType = OptionType.BOOLEAN;
        } else if (callback instanceof ProgramDirectory.DirectoryCallback
            && !callback.isReadOnly()) {
          optionType = OptionType.DIRECTORY;
        } else if (!callback.isReadOnly()) {
          optionType = OptionType.TEXT;
        } else /* if (callback.isReadOnly()) */ {
          optionType = OptionType.TEXT_READ_ONLY;
        }

        // If ConfigToadlet is serving a plugin, ask the plugin to
        // translate the
        // config descriptions, otherwise use the node's BaseL10n
        // instance like
        // normal.
        HTMLNode shortDesc = o.getShortDescNode(plugin);
        HTMLNode longDesc = o.getLongDescNode(plugin);

        HTMLNode configItemNode = configGroupUlNode.addChild("li");
        String defaultValue;
        if (callback instanceof BooleanCallback) {
          // Only case where values are localised.
          defaultValue = l10n(Boolean.toString(Boolean.valueOf(value)));
        } else {
          defaultValue = o.getDefault();
        }

        configItemNode.addAttribute("class", optionType.cssClass);
        configItemNode
            .addChild("a", new String[] {"name", "id"}, new String[] {configName, configName})
            .addChild(
                "span",
                new String[] {"class", "title", "style"},
                new String[] {
                  "configshortdesc",
                  NodeL10n.getBase()
                          .getString(
                              "ConfigToadlet.defaultIs",
                              new String[] {"default"},
                              new String[] {defaultValue})
                      + (advancedModeEnabled ? " [" + fullName + ']' : ""),
                  "cursor: help;"
                })
            .addChild(shortDesc);
        HTMLNode configItemValueNode = configItemNode.addChild("span", "class", "config");

        // Values persisted through browser or backing down from
        // resetting to defaults
        // override the currently applied ones.
        if (req.isPartSet(fullName)) {
          value = req.getPartAsStringFailsafe(fullName, MAX_PARAM_VALUE_SIZE);
        }
        if (overriddenOption != null && overriddenOption.equals(fullName)) value = overriddenValue;
        switch (optionType) {
          case DROP_DOWN:
            configItemValueNode.addChild(
                addComboBox(
                    value, (EnumerableOptionCallback) callback, fullName, callback.isReadOnly()));
            break;
          case BOOLEAN:
            configItemValueNode.addChild(
                addBooleanComboBox(Boolean.valueOf(value), fullName, callback.isReadOnly()));
            break;
          case DIRECTORY:
            configItemValueNode.addChild(addTextBox(value, fullName, o, false));
            configItemValueNode.addChild(
                "input",
                new String[] {"type", "name", "value"},
                new String[] {
                  "submit",
                  "select-directory." + fullName,
                  NodeL10n.getBase().getString("QueueToadlet.browseToChange")
                });
            break;
          case TEXT_READ_ONLY:
            configItemValueNode.addChild(addTextBox(value, fullName, o, true));
            break;
          case TEXT:
            configItemValueNode.addChild(addTextBox(value, fullName, o, false));
            break;
        }

        configItemNode.addChild("span", "class", "configlongdesc").addChild(longDesc);
      }
    }

    if (displayedConfigElements > 0) {
      formNode.addChild(
          "div",
          "class",
          "configprefix",
          (plugin == null) ? l10n(subConfig.getPrefix()) : plugin.getString(subConfig.getPrefix()));
      formNode.addChild("a", "id", subConfig.getPrefix());
      formNode.addChild(configGroupUlNode);
    }

    formNode.addChild(
        "input", new String[] {"type", "value"}, new String[] {"submit", l10n("apply")});
    formNode.addChild(
        "input", new String[] {"type", "value"}, new String[] {"reset", l10n("undo")});
    formNode.addChild(
        "input",
        new String[] {"type", "name", "value"},
        new String[] {"hidden", "subconfig", subConfig.getPrefix()});
    // 'Node' prefix options should not be reset to defaults as it is a,
    // quoting Toad, "very bad idea".
    // Options whose defaults are not wise to apply include the location of
    // the master keys file,
    // the Darknet port number, and the datastore size.
    if (!subConfig.getPrefix().equals("node")) {
      formNode.addChild(
          "input",
          new String[] {"type", "name", "value"},
          new String[] {"submit", "confirm-reset-to-defaults", l10n("resetToDefaults")});
    }

    this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
  }