def post(self, request, format=None): try: tags = validate_data_param(request, 'SWID tags') except ValueError as e: return e.message # Process tags stats = {'added': 0, 'replaced': 0} for tag in tags: try: tag, replaced = utils.process_swid_tag(tag) except XMLSyntaxError: return make_message('Invalid XML', status.HTTP_400_BAD_REQUEST) except ValueError as e: return make_message(unicode(e), status.HTTP_400_BAD_REQUEST) else: # Update stats if replaced: stats['replaced'] += 1 else: stats['added'] += 1 msg = 'Added {0[added]} SWID tags, replaced {0[replaced]} SWID tags.'.format( stats) return make_message(msg, status.HTTP_200_OK)
def validate_data_param(request, list_name): """ Validate data for API views that expect a data=[] like parameter. If validation fails, a ValueError is raised, with the response as exception message. Otherwise, the list is returned. """ if hasattr(request.DATA, 'getlist'): items = request.DATA.getlist('data') elif hasattr(request.DATA, 'get'): items = request.DATA.get('data') else: response = make_message('Missing "data" parameter', status.HTTP_400_BAD_REQUEST) raise ValueError(response) if items is None: response = make_message('Missing "data" parameter', status.HTTP_400_BAD_REQUEST) raise ValueError(response) if not items: response = make_message('No %s submitted' % list_name, status.HTTP_400_BAD_REQUEST) raise ValueError(response) if not isinstance(items, list): msg = 'The submitted "data" parameter does not contain a list' response = make_message(msg, status.HTTP_400_BAD_REQUEST) raise ValueError(response) return items
def post(self, request, pk, format=None): try: software_ids = validate_data_param(request, 'software IDs') except ValueError as e: return e.message found_tag_qs = Tag.objects.values_list('software_id', 'pk') found_tags = dict( utils.chunked_filter_in(found_tag_qs, 'software_id', software_ids, 980)) # Look for matching tags missing_tags = [] for software_id in software_ids: if software_id not in found_tags: missing_tags.append(software_id) if missing_tags: # Some tags are missing return Response(data=missing_tags, status=status.HTTP_412_PRECONDITION_FAILED) else: # All tags are available: link them with a session try: session = Session.objects.get(pk=pk) except Session.DoesNotExist: msg = 'Session with id "%s" not found' % pk return make_message(msg, status.HTTP_404_NOT_FOUND) utils.chunked_bulk_add(session.tag_set, found_tags.values(), 980) # Update tag stats # Also possible with signaling https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed utils.update_tag_stats(session, found_tags.values()) return Response(data=[], status=status.HTTP_200_OK)
def post(self, request, pk, format=None): try: software_ids = validate_data_param(request, 'software IDs') except ValueError as e: return e.message found_tag_qs = Tag.objects.values_list('software_id', 'pk') found_tags = dict(utils.chunked_filter_in(found_tag_qs, 'software_id', software_ids, 980)) # Look for matching tags missing_tags = [] for software_id in software_ids: if software_id not in found_tags: missing_tags.append(software_id) if missing_tags: # Some tags are missing return Response(data=missing_tags, status=status.HTTP_412_PRECONDITION_FAILED) else: # All tags are available: link them with a session try: session = Session.objects.get(pk=pk) except Session.DoesNotExist: msg = 'Session with id "%s" not found' % pk return make_message(msg, status.HTTP_404_NOT_FOUND) utils.chunked_bulk_add(session.tag_set, found_tags.values(), 980) # Update tag stats # Also possible with signaling https://docs.djangoproject.com/en/dev/ref/signals/#m2m-changed utils.update_tag_stats(session, found_tags.values()) return Response(data=[], status=status.HTTP_200_OK)
def post(self, request, format=None): try: tags = validate_data_param(request, 'SWID tags') except ValueError as e: return e.message # Publish SWID tags on XMPP-Grid? xmpp_connected = False if USE_XMPP: # Initialize XMPP client xmpp = XmppGridClient(XMPP_GRID['jid'], XMPP_GRID['password'], XMPP_GRID['pubsub_server']) xmpp.ca_certs = XMPP_GRID['cacert'] xmpp.certfile = XMPP_GRID['certfile'] xmpp.keyfile = XMPP_GRID['keyfile'] xmpp.use_ipv6 = XMPP_GRID['use_ipv6'] # Connect to the XMPP server and start processing XMPP stanzas. if xmpp.connect(): xmpp.process() xmpp_connected = True # Process tags stats = {'added': 0, 'replaced': 0} for tag in tags: try: tag, replaced = utils.process_swid_tag(tag) except XMLSyntaxError: return make_message('Invalid XML', status.HTTP_400_BAD_REQUEST) except ValueError as e: return make_message(unicode(e), status.HTTP_400_BAD_REQUEST) else: # Update stats if replaced: stats['replaced'] += 1 else: stats['added'] += 1 if xmpp_connected: xmpp.publish(XMPP_GRID['node_swidtags'], tag.software_id, tag.json()) if xmpp_connected: xmpp.disconnect() msg = 'Added {0[added]} SWID tags, replaced {0[replaced]} SWID tags.'.format( stats) return make_message(msg, status.HTTP_200_OK)
def post(self, request, format=None): try: tags = validate_data_param(request, 'SWID tags') except ValueError as e: return e.message # Process tags stats = {'added': 0, 'replaced': 0} for tag in tags: try: tag, replaced = utils.process_swid_tag(tag) except XMLSyntaxError: return make_message('Invalid XML', status.HTTP_400_BAD_REQUEST) except ValueError as e: return make_message(unicode(e), status.HTTP_400_BAD_REQUEST) else: # Update stats if replaced: stats['replaced'] += 1 else: stats['added'] += 1 msg = 'Added {0[added]} SWID tags, replaced {0[replaced]} SWID tags.'.format(stats) return make_message(msg, status.HTTP_200_OK)
def post(self, request, pk, format=None): try: obj = request.DATA # Check if any software identifiers, i.e. Tags are missing missing_tags = [] for e in obj['events']: sw_id = e['softwareId'] if not Tag.objects.filter(software_id=sw_id).exists(): if sw_id not in missing_tags: missing_tags.append(sw_id) if missing_tags: return Response(data=missing_tags, status=status.HTTP_412_PRECONDITION_FAILED) # Get current Session object try: session = Session.objects.get(pk=pk) except Session.DoesNotExist: msg = 'Session with id "%s" not found' % pk return make_message(msg, status.HTTP_404_NOT_FOUND) # Publish SWID events on XMPP-Grid? xmpp_connected = False if USE_XMPP: # Initialize XMPP client xmpp = XmppGridClient(XMPP_GRID['jid'], XMPP_GRID['password'], XMPP_GRID['pubsub_server']) xmpp.ca_certs = XMPP_GRID['cacert'] xmpp.certfile = XMPP_GRID['certfile'] xmpp.keyfile = XMPP_GRID['keyfile'] xmpp.use_ipv6 = XMPP_GRID['use_ipv6'] # Connect to the XMPP server and start processing XMPP stanzas. if xmpp.connect(): xmpp.process() xmpp_connected = True # Create Event and TagEvent objects if they don't exist yet epoch = obj['epoch'] last_eid = obj['lastEid'] for e in obj['events']: action = e['action'] ev, _ = Event.objects.get_or_create(device=session.device, epoch=epoch, eid=e['eid'], timestamp=e['timestamp']) t = Tag.objects.get(software_id=e['softwareId']) te, _ = TagEvent.objects.get_or_create(event=ev, tag=t, record_id=e['recordId'], source_id=e['sourceId'], action=action) if xmpp_connected: j_event = '"event": {"timestamp": "%s", "epoch": "%s", "eid": "%s"}' % \ (e['timestamp'], epoch, e['eid']) j_device = '"device": {"value": "%s", "description": "%s"}' % \ (session.device.value, session.device.description) j_tag = '"tag": {"softwareId": "%s", "recordId": %s, "sourceId": %s}' % \ (e['softwareId'], e['recordId'], e['sourceId']) j_action = '"action": %d' % action j_data = '{%s, %s, %s, %s}' % (j_event, j_device, j_tag, j_action) xmpp.publish(XMPP_GRID['node_events'], None, j_data) # Update tag stats ts_set = TagStats.objects.filter(device=session.device, tag=t) if ts_set: ts = ts_set[0] if action == TagEvent.CREATION: ts.last_deleted = None else: ts.last_deleted = ev ts.last_seen = session ts.save() else: ts = TagStats.objects.create(device=session.device, tag=t, first_seen=session, last_seen=session, first_installed=ev) if xmpp_connected: xmpp.disconnect() return Response(data=[], status=status.HTTP_200_OK) except ValueError as e: return e.message