diff --git a/upvote/gae/bigquery/tables.py b/upvote/gae/bigquery/tables.py
index 1002c46..3d6aafa 100644
--- a/upvote/gae/bigquery/tables.py
+++ b/upvote/gae/bigquery/tables.py
@@ -365,6 +365,7 @@ def InsertRow(self, **kwargs):
Column(name='client', choices=constants.CLIENT.SET_ALL),
Column(name='first_seen_file_name', mode=MODE.NULLABLE),
Column(name='cert_fingerprint', mode=MODE.NULLABLE),
+ Column(name='is_compiler', field_type=FIELD_TYPE.BOOLEAN),
Column(name='comment', mode=MODE.NULLABLE)])
diff --git a/upvote/gae/datastore/models/base.py b/upvote/gae/datastore/models/base.py
index 623961f..835d0ec 100644
--- a/upvote/gae/datastore/models/base.py
+++ b/upvote/gae/datastore/models/base.py
@@ -239,6 +239,9 @@ def _CalculateScore(self):
score = ndb.ComputedProperty(_CalculateScore)
+ # FBN
+ is_compiler = ndb.BooleanProperty(default=False)
+
def ChangeState(self, new_state):
"""Helper method for changing the state of this Blockable.
@@ -399,6 +402,7 @@ def TranslatePropertyQuery(cls, field, value):
def to_dict(self, include=None, exclude=None): # pylint: disable=g-bad-name
result = super(Binary, self).to_dict(include=include, exclude=exclude)
result['cert_id'] = self.cert_id
+ result['is_compiler'] = self.is_compiler
return result
def InsertBigQueryRow(self, action, **kwargs):
@@ -412,7 +416,8 @@ def InsertBigQueryRow(self, action, **kwargs):
'platform': self.GetPlatformName(),
'client': self.GetClientName(),
'first_seen_file_name': self.file_name,
- 'cert_fingerprint': self.cert_id}
+ 'cert_fingerprint': self.cert_id,
+ 'is_compiler': self.is_compiler}
defaults.update(kwargs.copy())
tables.BINARY.InsertRow(**defaults)
diff --git a/upvote/gae/lib/voting/api.py b/upvote/gae/lib/voting/api.py
index 7ac39a3..db938d4 100644
--- a/upvote/gae/lib/voting/api.py
+++ b/upvote/gae/lib/voting/api.py
@@ -560,14 +560,18 @@ def _GloballyWhitelist(self):
# Disable all local or blacklisting rules.
changed_rules = []
for rule in existing_rules:
- if rule.policy != constants.RULE_POLICY.WHITELIST or rule.host_id:
+ if rule.policy not in {constants.RULE_POLICY.WHITELIST,
+ constants.RULE_POLICY.WHITELIST_COMPILER} or rule.host_id:
rule.MarkDisabled()
changed_rules.append(rule)
# Create the new globally whitelist rule.
- whitelist_rule = self._GenerateRule(
- policy=constants.RULE_POLICY.WHITELIST,
- in_effect=True)
+ if self.blockable.is_compiler:
+ policy = constants.RULE_POLICY.WHITELIST_COMPILER
+ else:
+ policy = constants.RULE_POLICY.WHITELIST
+
+ whitelist_rule = self._GenerateRule(policy=policy, in_effect=True)
whitelist_rule.InsertBigQueryRow()
# Put all new/modified Rules.
@@ -619,8 +623,13 @@ def _CreateNewLocalWhitelistingRules(self, local_rule_dict):
# Otherwise, create a new Rule to persist.
else:
logging.info('Creating new Rule for %s on %s', user_key.id(), host_id)
+ if self.blockable.is_compiler:
+ policy = constants.RULE_POLICY.WHITELIST_COMPILER
+ else:
+ policy = constants.RULE_POLICY.WHITELIST
+
new_rule = self._GenerateRule(
- policy=constants.RULE_POLICY.WHITELIST,
+ policy=policy,
in_effect=True,
host_id=host_id,
user_key=user_key)
diff --git a/upvote/gae/modules/upvote_app/api/web/blockables.py b/upvote/gae/modules/upvote_app/api/web/blockables.py
index 184e5d5..2aaac29 100644
--- a/upvote/gae/modules/upvote_app/api/web/blockables.py
+++ b/upvote/gae/modules/upvote_app/api/web/blockables.py
@@ -226,6 +226,9 @@ def post(self, blockable_id): # pylint: disable=g-bad-name
"""Post handler for blockables."""
blockable_id = blockable_id.lower()
logging.info('Blockable handler POST input: %s', self.request.arguments())
+ blockable = base_models.Blockable.get_by_id(blockable_id)
+ with_context = (self.request.get('withContext').lower() == 'true')
+
if self.request.get('recount').lower() == 'recount':
try:
voting_api.Recount(blockable_id)
@@ -235,16 +238,25 @@ def post(self, blockable_id): # pylint: disable=g-bad-name
self.abort(httplib.BAD_REQUEST, explanation='Unsupported platform')
except Exception as e: # pylint: disable=broad-except
self.abort(httplib.INTERNAL_SERVER_ERROR, explanation=e.message)
- else:
- blockable = base_models.Blockable.get_by_id(blockable_id)
-
- with_context = (self.request.get('withContext').lower() == 'true')
- response_data = _GetBlockableContext([blockable])[0] if with_context else blockable
- self.respond_json(response_data)
elif self.request.get('reset').lower() == 'reset':
- self._reset_blockable(blockable_id)
+ blockable = self._reset_blockable(blockable_id)
+ elif blockable is not None:
+ blockable = self._update_blockable(blockable)
else:
- self._insert_blockable(blockable_id, datetime.datetime.utcnow())
+ blockable = self._insert_blockable(blockable_id, datetime.datetime.utcnow())
+
+ response_data = _GetBlockableContext([blockable])[0] if with_context else blockable
+ self.respond_json(response_data)
+
+ # TODO: should really be UPDATE_BLOCKABLES
+ @base.RequireCapability(constants.PERMISSIONS.INSERT_BLOCKABLES)
+ def _update_blockable(self, blockable):
+ if isinstance(blockable, base_models.Binary):
+ if self.request.get('isCompiler') is not None:
+ blockable.is_compiler = self.request.get('isCompiler') == 'true'
+
+ blockable.put()
+ return blockable
@ndb.transactional(xg=True) # xg because respond_json() touches User.
@base.RequireCapability(constants.PERMISSIONS.INSERT_BLOCKABLES)
@@ -293,7 +305,7 @@ def _insert_blockable(self, blockable_id, timestamp):
blockable.notes.append(note.key)
blockable.put()
- self.respond_json(blockable)
+ return blockable
@base.RequireCapability(constants.PERMISSIONS.RESET_BLOCKABLE_STATE)
def _reset_blockable(self, blockable_id):
@@ -310,7 +322,7 @@ def _reset_blockable(self, blockable_id):
self.abort(httplib.INTERNAL_SERVER_ERROR, explanation=e.message)
else:
blockable = base_models.Blockable.get_by_id(blockable_id)
- self.respond_json(blockable)
+ return blockable
class AuthorizedHostCountHandler(base.BaseHandler):
@@ -506,6 +518,7 @@ def _SetInstallerPolicy(self, blockable_id, new_policy):
client=constants.CLIENT.BIT9,
first_seen_file_name=blockable.first_seen_name,
cert_fingerprint=blockable.cert_id,
+ is_compiler=blockable.is_compiler,
comment=message)
change_set.DeferCommitBlockableChangeSet(blockable.key)
diff --git a/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockablepage-controller.js b/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockablepage-controller.js
index bf27af6..99bb8e6 100644
--- a/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockablepage-controller.js
+++ b/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockablepage-controller.js
@@ -213,6 +213,25 @@ upvote.admin.blockablepage.BlockableController = class extends ModelController {
}
}
+ /**
+ * Toggles the isCompiler state of the blockable
+ * @export
+ */
+ toggleCompiler() {
+ let orig_isCompiler = this.card['isCompiler'];
+ this.card['isCompiler'] = !this.card['isCompiler'];
+
+ this.resource.update({'id': this.id, 'isCompiler': this.card['isCompiler']})['$promise']
+ .then((card) => {
+ //this.loadCard();
+ // nop
+ })
+ .catch((reason) => {
+ this.card['isCompiler'] = orig_isCompiler;
+ this.errorService_.createDialogFromError(reason);
+ });
+ }
+
/**
* Upvote the current Blockable
* @export
@@ -235,7 +254,15 @@ upvote.admin.blockablepage.BlockableController = class extends ModelController {
*/
reset() {
if (this.id) {
- this.resource['reset']({'id': this.id});
+ this.resource['reset']({'id': this.id})['$promise']
+ .then((card) => {
+ //this.loadCard();
+ this.card = card;
+ })
+ .catch((reason) => {
+ this.card['isCompiler'] = orig_isCompiler;
+ this.errorService_.createDialogFromError(reason);
+ });
}
}
diff --git a/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockables.html b/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockables.html
index 5f6ba4b..87c84f9 100644
--- a/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockables.html
+++ b/upvote/gae/modules/upvote_app/frontend/admin_ui/blockablepage/blockables.html
@@ -19,6 +19,20 @@