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; }
/** {@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()); }