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 @@ Down Vote + + + + Set Compiler + + + Unset Compiler + + + Admin Link diff --git a/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-card.html b/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-card.html index 61eeb66..d107b65 100644 --- a/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-card.html +++ b/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-card.html @@ -53,6 +53,9 @@
Score: {{ card.score }}
+
+ Is Compiler: {{ card.isCompiler }} +
First Seen: {{ card.occurredDt }}
diff --git a/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-resource.js b/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-resource.js index 0143270..80e2d42 100644 --- a/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-resource.js +++ b/upvote/gae/modules/upvote_app/frontend/admin_ui/components/blockables/blockable-resource.js @@ -46,6 +46,13 @@ upvote.admin.blockables.BlockableResource = buildResource(API_PREFIX + ':id', { 'id': '@id', 'reset': 'reset', }, + }, + 'update': { + 'method': 'POST', + 'params': { + 'id': '@id', + 'isCompiler': '@isCompiler' + } } }); diff --git a/upvote/gae/modules/upvote_app/frontend/web_ui/shared/models.js b/upvote/gae/modules/upvote_app/frontend/web_ui/shared/models.js index 9f8e4e4..68901a2 100644 --- a/upvote/gae/modules/upvote_app/frontend/web_ui/shared/models.js +++ b/upvote/gae/modules/upvote_app/frontend/web_ui/shared/models.js @@ -64,7 +64,9 @@ goog.provide('upvote.shared.models.Vote'); * isInstaller: boolean, * md5: string, * productVersion: string, - * sha1: string + * sha1: string, + * + * isCompiler: boolean, * }} */ upvote.shared.models.Bit9Binary; @@ -94,6 +96,8 @@ upvote.shared.models.Bit9Binary; * votingProhibitedReason: string, * * bundleId: string, + * + * isCompiler: boolean, * }} */ upvote.shared.models.SantaBlockable;