Browse Source

allow multiple matchers to coordinate icon display

pull/43/head
Jonathan Cobb 4 years ago
parent
commit
35596dd5d2
9 changed files with 90 additions and 47 deletions
  1. +23
    -11
      bubble-server/src/main/java/bubble/rule/AbstractAppRuleDriver.java
  2. +0
    -2
      bubble-server/src/main/java/bubble/rule/AppRuleDriver.java
  3. +6
    -0
      bubble-server/src/main/java/bubble/rule/RequestModifierRule.java
  4. +9
    -7
      bubble-server/src/main/java/bubble/rule/bblock/BubbleBlockRuleDriver.java
  5. +2
    -4
      bubble-server/src/main/java/bubble/rule/social/block/JsUserBlockerRuleDriver.java
  6. +33
    -0
      bubble-server/src/main/resources/bubble/rule/RequestModifierRule_icon.js.hbs
  7. +2
    -0
      bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver.js.hbs
  8. +7
    -0
      bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver_stats.js.hbs
  9. +8
    -23
      bubble-server/src/main/resources/bubble/rule/social/block/JsUserBlockerRuleDriver.js.hbs

+ 23
- 11
bubble-server/src/main/java/bubble/rule/AbstractAppRuleDriver.java View File

@@ -36,22 +36,18 @@ import java.util.HashMap;
import java.util.Map;

import static bubble.ApiConstants.HOME_DIR;
import static bubble.rule.RequestModifierRule.ICON_JS_TEMPLATE;
import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.io.regex.RegexReplacementFilter.DEFAULT_PREFIX_REPLACEMENT_WITH_MATCH;
import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.security.ShaUtil.sha256_hex;
import static org.cobbzilla.util.string.StringUtil.UTF8cs;

public abstract class AbstractAppRuleDriver implements AppRuleDriver {

public static final int RESPONSE_BUFSIZ = (int) (64 * Bytes.KB);

public static final String CTX_JS_PREFIX = "JS_PREFIX";
public static final String CTX_BUBBLE_REQUEST_ID = "BUBBLE_REQUEST_ID";
public static final String CTX_BUBBLE_DATA_ID = "BUBBLE_DATA_ID";
public static final String CTX_BUBBLE_HOME = "BUBBLE_HOME";
public static final String CTX_SITE = "SITE";

@Autowired protected BubbleConfiguration configuration;
@Autowired protected AppDataDAO appDataDAO;
@Autowired protected AppSiteDAO appSiteDAO;
@@ -139,11 +135,12 @@ public abstract class AbstractAppRuleDriver implements AppRuleDriver {
Map<String, Object> filterCtx,
String bubbleJsTemplate,
String defaultSiteTemplate,
String siteJsInsertionVar) {
String siteJsInsertionVar,
boolean showIcon) {
final RequestModifierConfig modConfig = requestModConfig();
final String replacement = DEFAULT_PREFIX_REPLACEMENT_WITH_MATCH
+ scriptOpen(filterRequest, modConfig.getScriptOpenNonce(), modConfig.getScriptOpenNoNonce())
+ getBubbleJs(filterRequest.getId(), filterCtx, bubbleJsTemplate, defaultSiteTemplate, siteJsInsertionVar)
+ getBubbleJs(filterRequest.getId(), filterCtx, bubbleJsTemplate, defaultSiteTemplate, siteJsInsertionVar, showIcon)
+ getScriptClose();

final RegexReplacementFilter filter = new RegexReplacementFilter(getInsertionRegex(), replacement);
@@ -162,20 +159,35 @@ public abstract class AbstractAppRuleDriver implements AppRuleDriver {
Map<String, Object> filterCtx,
String bubbleJsTemplate,
String defaultSiteTemplate,
String siteJsInsertionVar) {
String siteJsInsertionVar,
boolean showIcon) {
final Map<String, Object> ctx = getBubbleJsContext(requestId, filterCtx);

if (!empty(siteJsInsertionVar) && !empty(defaultSiteTemplate)) {
final String siteJs = HandlebarsUtil.apply(getHandlebars(), getSiteJsTemplate(defaultSiteTemplate), ctx);
ctx.put(siteJsInsertionVar, siteJs);
}

if (showIcon) {
ctx.put(CTX_ICON_JS, HandlebarsUtil.apply(getHandlebars(), ICON_JS_TEMPLATE, ctx));
}
return HandlebarsUtil.apply(getHandlebars(), bubbleJsTemplate, ctx);
}

public static final String CTX_JS_PREFIX = "JS_PREFIX";
public static final String CTX_PAGE_PREFIX = "PAGE_PREFIX";
public static final String CTX_BUBBLE_REQUEST_ID = "BUBBLE_REQUEST_ID";
public static final String CTX_BUBBLE_DATA_ID = "BUBBLE_DATA_ID";
public static final String CTX_BUBBLE_HOME = "BUBBLE_HOME";
public static final String CTX_SITE = "SITE";
public static final String CTX_ICON_JS = "ICON_JS";

private String getPagePrefix(String requestId) { return "__bubble_"+sha256_hex(requestId); }
private String getJsPrefix(String requestId) { return "__bubble_"+sha256_hex(requestId+"_"+getClass().getName()); }

protected Map<String, Object> getBubbleJsContext(String requestId, Map<String, Object> filterCtx) {
final Map<String, Object> ctx = new HashMap<>();
ctx.put(CTX_JS_PREFIX, AppRuleDriver.getJsPrefix(requestId));
ctx.put(CTX_PAGE_PREFIX, getPagePrefix(requestId));
ctx.put(CTX_JS_PREFIX, getJsPrefix(requestId));
ctx.put(CTX_BUBBLE_REQUEST_ID, requestId);
ctx.put(CTX_BUBBLE_HOME, configuration.getPublicUriBase());
ctx.put(CTX_SITE, getSiteName(matcher));


+ 0
- 2
bubble-server/src/main/java/bubble/rule/AppRuleDriver.java View File

@@ -114,8 +114,6 @@ public interface AppRuleDriver {

default Handlebars getHandlebars() { return null; }

static String getJsPrefix(String requestId) { return "__bubble_"+sha256_hex(requestId)+"_"; }

default String locateResource(String res) {
if (!res.startsWith("@")) return res;
final String prefix = getPackagePath(getClass()) + "/" + getClass().getSimpleName();


+ 6
- 0
bubble-server/src/main/java/bubble/rule/RequestModifierRule.java View File

@@ -4,8 +4,14 @@
*/
package bubble.rule;

import static org.cobbzilla.util.io.StreamUtil.stream2string;
import static org.cobbzilla.util.string.StringUtil.getPackagePath;

public interface RequestModifierRule {

RequestModifierConfig getRequestModifierConfig ();

Class<RequestModifierRule> RMR = RequestModifierRule.class;
String ICON_JS_TEMPLATE = stream2string(getPackagePath(RMR)+"/"+ RMR.getSimpleName()+"_icon.js.hbs");

}

+ 9
- 7
bubble-server/src/main/java/bubble/rule/bblock/BubbleBlockRuleDriver.java View File

@@ -40,6 +40,7 @@ import static org.cobbzilla.util.http.HttpContentTypes.isHtml;
import static org.cobbzilla.util.io.StreamUtil.stream2string;
import static org.cobbzilla.util.json.JsonUtil.COMPACT_MAPPER;
import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.string.StringUtil.EMPTY;
import static org.cobbzilla.util.string.StringUtil.getPackagePath;

@Slf4j
@@ -286,6 +287,7 @@ public class BubbleBlockRuleDriver extends TrafficAnalyticsRuleDriver implements
}

public static final String FILTER_CTX_DECISION = "decision";
public static final String BLOCK_STATS_JS = "BLOCK_STATS_JS";

@Override public InputStream doFilterResponse(FilterHttpRequest filterRequest, InputStream in) {

@@ -333,24 +335,24 @@ public class BubbleBlockRuleDriver extends TrafficAnalyticsRuleDriver implements
return in;
}

if (!bubbleBlockConfig.inPageBlocks() && !bubbleBlockConfig.showStats()) {
final boolean showStats = bubbleBlockConfig.showStats();
if (!bubbleBlockConfig.inPageBlocks() && !showStats) {
if (log.isInfoEnabled()) log.info(prefix + "SEND: both inPageBlocks and showStats are false, returning as-is");
return in;
}
if (bubbleBlockConfig.inPageBlocks() && bubbleBlockConfig.showStats()) {
return filterInsertJs(in, filterRequest, filterCtx, BUBBLE_JS_BOTH_TEMPLATE, null, null);
if (bubbleBlockConfig.inPageBlocks() && showStats) {
return filterInsertJs(in, filterRequest, filterCtx, BUBBLE_JS_TEMPLATE, BUBBLE_JS_STATS_TEMPLATE, BLOCK_STATS_JS, showStats);
}
if (bubbleBlockConfig.inPageBlocks()) {
return filterInsertJs(in, filterRequest, filterCtx, BUBBLE_JS_TEMPLATE, null, null);
return filterInsertJs(in, filterRequest, filterCtx, BUBBLE_JS_TEMPLATE, EMPTY, BLOCK_STATS_JS, showStats);
}
log.warn(prefix+"doFilterResponse: inserting JS for stats...");
return filterInsertJs(in, filterRequest, filterCtx, BUBBLE_JS_STATS_TEMPLATE, null, null);
log.warn(prefix+"inserting JS for stats...");
return filterInsertJs(in, filterRequest, filterCtx, BUBBLE_JS_STATS_TEMPLATE, null, null, showStats);
}

public static final Class<BubbleBlockRuleDriver> BB = BubbleBlockRuleDriver.class;
public static final String BUBBLE_JS_TEMPLATE = stream2string(getPackagePath(BB)+"/"+ BB.getSimpleName()+".js.hbs");
public static final String BUBBLE_JS_STATS_TEMPLATE = stream2string(getPackagePath(BB)+"/"+ BB.getSimpleName()+"_stats.js.hbs");
public static final String BUBBLE_JS_BOTH_TEMPLATE = BUBBLE_JS_TEMPLATE + "\n\n" + BUBBLE_JS_STATS_TEMPLATE;

private static final String CTX_BUBBLE_SELECTORS = "BUBBLE_SELECTORS_JSON";
private static final String CTX_BUBBLE_BLACKLIST = "BUBBLE_BLACKLIST_JSON";


+ 2
- 4
bubble-server/src/main/java/bubble/rule/social/block/JsUserBlockerRuleDriver.java View File

@@ -8,7 +8,6 @@ import bubble.resources.stream.FilterHttpRequest;
import bubble.rule.AbstractAppRuleDriver;
import bubble.rule.RequestModifierConfig;
import bubble.rule.RequestModifierRule;
import bubble.rule.bblock.BubbleBlockConfig;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@@ -16,7 +15,6 @@ import java.io.InputStream;

import static org.cobbzilla.util.http.HttpContentTypes.isHtml;
import static org.cobbzilla.util.io.StreamUtil.stream2string;
import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.string.StringUtil.getPackagePath;

@Slf4j
@@ -37,7 +35,7 @@ public class JsUserBlockerRuleDriver extends AbstractAppRuleDriver implements Re

@Override public InputStream doFilterResponse(FilterHttpRequest filterRequest, InputStream in) {
if (!isHtml(filterRequest.getContentType())) return in;
log.warn("doFilterResponse: inserting JS, getRequestModifierConfig()="+json(getRequestModifierConfig()));
return filterInsertJs(in, filterRequest, null, BUBBLE_JS_TEMPLATE, getDefaultSiteJsTemplate(), CTX_APPLY_BLOCKS_JS);
log.warn("doFilterResponse("+filterRequest.getId()+"): inserting JS");
return filterInsertJs(in, filterRequest, null, BUBBLE_JS_TEMPLATE, getDefaultSiteJsTemplate(), CTX_APPLY_BLOCKS_JS, true);
}
}

+ 33
- 0
bubble-server/src/main/resources/bubble/rule/RequestModifierRule_icon.js.hbs View File

@@ -0,0 +1,33 @@

if (typeof {{PAGE_PREFIX}}_icon_status === 'undefined') {
let {{PAGE_PREFIX}}_doc_ready = false;
const {{PAGE_PREFIX}}_interval = 50;

{{PAGE_PREFIX}}_icon_status = [];

function {{PAGE_PREFIX}}_onReady(callback) {
const intervalId = window.setInterval(function() {
if (document.getElementsByTagName('body')[0] !== undefined) {
{{PAGE_PREFIX}}_doc_ready = true;
window.clearInterval(intervalId);
callback.call(this);
}
}, {{PAGE_PREFIX}}_interval);
}

{{PAGE_PREFIX}}_onReady(function() {
const controlDivId = '{{PAGE_PREFIX}}_controlDiv';
let bubbleControlDiv = document.getElementById(controlDivId);
if (bubbleControlDiv === null) {
bubbleControlDiv = document.createElement('div');
bubbleControlDiv.id = controlDivId;
bubbleControlDiv.style.position = 'fixed';
bubbleControlDiv.style.bottom = '0';
bubbleControlDiv.style.right = '0';
document.getElementsByTagName('body')[0].appendChild(bubbleControlDiv);
}
for (let i=0; i<{{PAGE_PREFIX}}_icon_status.length; i++) {
bubbleControlDiv.innerHTML = bubbleControlDiv.innerHTML + {{PAGE_PREFIX}}_icon_status[i].iconHtml;
}
});
}

+ 2
- 0
bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver.js.hbs View File

@@ -326,3 +326,5 @@ function {{JS_PREFIX}}_process_filters() {
{{JS_PREFIX}}_process_filters();
window.setInterval({{JS_PREFIX}}_process_filters, {{JS_PREFIX}}_idle_interval);
});

{{{BLOCK_STATS_JS}}}

+ 7
- 0
bubble-server/src/main/resources/bubble/rule/bblock/BubbleBlockRuleDriver_stats.js.hbs View File

@@ -1,3 +1,10 @@
//
// block stats js goes here
//
{{{ICON_JS}}}

{{PAGE_PREFIX}}_icon_status.push({
jsPrefix: '{{JS_PREFIX}}',
iconHtml: '<br/><a href="{{{BUBBLE_HOME}}}/app/BubbleBlock/view/last_24_hours"><img width="64" src="/__bubble/api/filter/assets/{{BUBBLE_REQUEST_ID}}/BubbleBlock/icon?raw=true"/></a>'
});
console.log("BubbleBlock pushed icon, {{PAGE_PREFIX}}_icon_status="+JSON.stringify({{PAGE_PREFIX}}_icon_status));

+ 8
- 23
bubble-server/src/main/resources/bubble/rule/social/block/JsUserBlockerRuleDriver.js.hbs View File

@@ -1,19 +1,10 @@
let {{JS_PREFIX}}_blocked_users = null;
let {{JS_PREFIX}}_doc_ready = false;
const {{JS_PREFIX}}_request_id = '{{BUBBLE_REQUEST_ID}}';

let {{JS_PREFIX}}_doc_ready = false;
const {{JS_PREFIX}}_interval = 50;
const {{JS_PREFIX}}_idle_interval = 1000;

function {{JS_PREFIX}}_onReady(callback) {
const intervalId = window.setInterval(function() {
if (document.getElementsByTagName('body')[0] !== undefined) {
{{JS_PREFIX}}_doc_ready = true;
window.clearInterval(intervalId);
callback.call(this);
}
}, {{JS_PREFIX}}_interval);
}

function {{JS_PREFIX}}_fetch_blocks (do_apply) {
const requestOptions = { method: 'GET' };
const blocked_users_url = '/__bubble/api/filter/data/{{BUBBLE_DATA_ID}}/read';
@@ -60,16 +51,10 @@ function {{JS_PREFIX}}_block_user (author) {

{{{APPLY_BLOCKS_JS}}}

{{JS_PREFIX}}_onReady(function() {
const controlDivId = '{{JS_PREFIX}}_controlDiv';
let bubbleControlDiv = document.getElementById(controlDivId);
if (bubbleControlDiv === null) {
bubbleControlDiv = document.createElement('div');
bubbleControlDiv.id = controlDivId;
bubbleControlDiv.style.position = 'fixed';
bubbleControlDiv.style.bottom = '0';
bubbleControlDiv.style.right = '0';
document.getElementsByTagName('body')[0].appendChild(bubbleControlDiv);
}
bubbleControlDiv.innerHTML = bubbleControlDiv.innerHTML + '<br/><a href="{{{BUBBLE_HOME}}}/app/UserBlocker/site/{{SITE}}/view/blocked_users"><img width="64" src="/__bubble/api/filter/assets/{{BUBBLE_REQUEST_ID}}/UserBlocker/icon?raw=true"/></a>';
{{{ICON_JS}}}

{{PAGE_PREFIX}}_icon_status.push({
jsPrefix: '{{JS_PREFIX}}',
iconHtml: '<br/><a href="{{{BUBBLE_HOME}}}/app/UserBlocker/site/{{SITE}}/view/blocked_users"><img width="64" src="/__bubble/api/filter/assets/{{BUBBLE_REQUEST_ID}}/UserBlocker/icon?raw=true"/></a>'
});
console.log("JsUserBlocker pushed icon, {{PAGE_PREFIX}}_icon_status="+JSON.stringify({{PAGE_PREFIX}}_icon_status));

Loading…
Cancel
Save