Пример #1
0
def main(dryrun=True):
    # TODO: Use wordlist instead of argument
    sensitive_words = ["sensitive"]

    aw = ActivityWatchClient(testing=True)

    re_word = r'\b{}\b'

    buckets = aw.get_buckets()
    for bid in buckets.keys():
        if "window" not in bid:
            continue

        print("Checking bucket: {}".format(bid))

        events = aw.get_events(bid, limit=-1)
        old_matches = set()
        for event in events:
            for key, val in event.data.items():
                if isinstance(val, str):
                    matches = [re.findall(re_word.format(word), val.lower())
                               for word in sensitive_words]
                    matches = set(sum(matches, []))
                    if matches:
                        event.data[key] = "REDACTED"
                        if val not in old_matches:
                            print(f"{'(DRYRUN) ' if dryrun else ''} Matches: {matches}, redacting: {val}")
                            old_matches.add(val)
                        if not dryrun:
                            aw.insert_event(bid, event)
Пример #2
0
def shutdown(bucket_name,start_time,end_time,activity):
    client = ActivityWatchClient("aw-watcher-cli", testing=False)
    bucket_id = "{}_{}".format(bucket_name, client.hostname)
    event_type = "cli_activity"
    client.create_bucket(bucket_id, event_type=event_type)
    shutdown_data = {"label": activity}
    shutdown_event = Event(timestamp=start_time, data=shutdown_data, duration=(end_time -start_time))
    inserted_event = client.insert_event(bucket_id, shutdown_event)
    rd = relativedelta.relativedelta (end_time, start_time)
    print("Spent {:02}:{:02}:{:02} doing {}:".format(rd.hours, rd.minutes, rd.seconds,activity))
Пример #3
0
class CLIWatcher:
    def __init__(self, bucket, etype, testing=False):
        self.client = ActivityWatchClient("aw-watcher-cli", testing=testing)
        self.bucketname = bucket
        self.etype = etype
        self.client.create_bucket(self.bucketname, event_type=self.etype)

    def run(self):
        logger.info(
            "aw-watcher-cli started for bucket '%s' containing events of type '%s'"
            % (self.bucketname, self.etype))

    def updateLastEvent(self):
        logger.info("Updating previous event duration.")
        try:
            last = self.client.get_events(bucket_id=self.bucketname,
                                          limit=1)[0]
        except IndexError:
            logger.info("No previous event found.")
            return

        duration = abs((datetime.now(timezone.utc) - last.timestamp).seconds)
        logger.info(
            "Previous event '%s' occurred at %s. Duration since: %ss" %
            (last.data, last.timestamp.strftime("%Y-%m-%d %T%z"), duration))
        last.duration = duration
        self.client.insert_event(self.bucketname, last)

    def addStringEvent(self, eventString, duration):
        logger.info("Adding event %s (duration: %s) to bucket %s" %
                    (eventString, duration, self.bucketname))
        data = {"label": eventString}
        event = Event(timestamp=datetime.now(timezone.utc),
                      data=data,
                      duration=duration)
        inserted_event = self.client.insert_event(self.bucketname, event)

        assert inserted_event.id is not None
def end_current_event(start_ts, category, item, end_dt=None):
    start_dt = datetime.utcfromtimestamp(start_ts)
    if end_dt is None:
        end_dt = datetime.utcnow()
    app.logger.debug('Instantiating client (127.0.0.1:5600)')
    client = ActivityWatchClient(
        "aw-watcher-manual-flaskweb", host='127.0.0.1:5600'
    )
    bucket_id = "{}_{}".format("aw-watcher-manual-flaskweb", client.hostname)
    app.logger.debug('Creating bucket: %s', bucket_id)
    client.create_bucket(bucket_id, event_type="currentwindow")
    t = 'manual: %s/%s' % (category, item)
    evt = Event(
        timestamp=start_dt, duration=(end_dt - start_dt).total_seconds(),
        data={'app': t, 'title': t, 'category': category, 'item': item}
    )
    inserted_event = client.insert_event(bucket_id, evt)
    app.logger.info('Inserted event: %s', inserted_event)
Пример #5
0
        # Sleep a second until next heartbeat
        sleep(sleeptime)

        # Update timestamp for next heartbeat
        heartbeat_event.timestamp = datetime.now(timezone.utc)

    # Give the dispatcher thread some time to complete sending the last events.
    # If we don't do this the events might possibly queue up and be sent the
    # next time the client starts instead.
    sleep(1)

# Synchronous example, insert an event
event_data = {"label": "non-heartbeat event"}
now = datetime.now(timezone.utc)
event = Event(timestamp=now, data=event_data)
inserted_event = client.insert_event(bucket_id, event)

# The event returned from insert_event has been assigned an id by aw-server
assert inserted_event.id is not None

# Fetch last 10 events from bucket
# Should be two events in order of newest to oldest
# - "shutdown" event with a duration of 0
# - "heartbeat" event with a duration of 5*sleeptime
events = client.get_events(bucket_id=bucket_id, limit=10)
print(events)

# Now lets clean up after us.
# You probably don't want this in your watchers though!
client.delete_bucket(bucket_id)
Пример #6
0
#!/usr/bin/env python3

from datetime import datetime, timezone

from aw_core.models import Event
from aw_client import ActivityWatchClient

# We'll run with testing=True so we don't mess up any production instance.
# Make sure you've started aw-server with the `--testing` flag as well.
client = ActivityWatchClient("test-client", testing=True)

bucket_id = "{}_{}".format("test-client-bucket", client.client_hostname)
client.create_bucket(bucket_id, event_type="dummydata")

shutdown_data = {"label": "some interesting data"}
now = datetime.now(timezone.utc)
shutdown_event = Event(timestamp=now, data=shutdown_data)
inserted_event = client.insert_event(bucket_id, shutdown_event)

events = client.get_events(bucket_id=bucket_id, limit=1)
print(events) # Should print a single event in a list

client.delete_bucket(bucket_id)
#!/usr/bin/env python3

from datetime import datetime, timezone

from aw_core.models import Event
from aw_client import ActivityWatchClient

# We'll run with testing=True so we don't mess up any production instance.
# Make sure you've started aw-server with the `--testing` flag as well.
client = ActivityWatchClient("test-client", testing=True)

bucket_id = "{}_{}".format("test-client-bucket", client.hostname)
client.create_bucket(bucket_id, event_type="dummydata")

shutdown_data = {"label": "some interesting data"}
now = datetime.now(timezone.utc)
shutdown_event = Event(timestamp=now, data=shutdown_data)
inserted_event = client.insert_event(bucket_id, shutdown_event)

events = client.get_events(bucket_id=bucket_id, limit=1)
print(events) # Should print a single event in a list

client.delete_bucket(bucket_id)
class MessageHandler:
    def __init__(self,
                 testing=False,
                 send_commands=True,
                 send_heartbeats=True):
        # Create client
        self._client = ActivityWatchClient(client_id, testing=testing)
        self._client.connect()
        self._init_buckets()

        # Settings
        self.pulsetime = 10
        self.send_commands = send_commands
        self.send_heartbeats = send_heartbeats

        # Initialize the EventQueue
        self._event_queue = EventQueue(callback=self._handle_event,
                                       time_buffer=(self.pulsetime / 2))

        self._event_handlers = {
            'preopen': self._preopen,
            'preexec': self._preexec,
            'precmd': self._precmd,
            'preclose': self._preclose
        }

        self._terminal_sessions = {}

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._client.disconnect()

    def _init_buckets(self):
        """Set self._buckets and create these buckets if not existing"""
        self._buckets = {
            'commands': {
                'id': "{}-commands_{}".format(client_id,
                                              self._client.hostname),
                'event_type': 'app.terminal.command'
            },
            'activity': {
                'id': "{}-activity_{}".format(client_id,
                                              self._client.hostname),
                'event_type': 'app.terminal.activity'
            }
        }

        # Create buckets if not existing
        for key, bucket in self._buckets.items():
            logger.debug("Creating bucket: {}".format(bucket['id']))
            self._client.create_bucket(bucket['id'],
                                       bucket['event_type'],
                                       queued=True)

    def update_event_queue(self):
        self._event_queue.update()

    def handle_fifo_message(self, message):
        for line in message.split('\n'):
            if not len(line):
                continue

            cli_args = shlex.split(line)
            args, unknown_args = parser_base.parse_known_args(cli_args)

            # Make sure that events are called in the right order
            # (based on args.timestamp) by passing it to the event queue
            # The event queue will trigger the callback when the time_buffer
            # is exceeded
            logger.debug("adding event to event_queue: {}".format(cli_args))
            self._event_queue.add_event(cli_args, args.timestamp)

    def _handle_event(self, cli_args):
        logger.debug("handling event: {}".format(cli_args))
        args, unknown_args = parser_base.parse_known_args(cli_args)

        # Store terminal session if not already existing
        pid = args.pid
        if pid not in self._terminal_sessions:
            self._terminal_sessions[pid] = TerminalSessionData(pid)

        if self.send_commands:
            if args.event not in self._event_handlers:
                logger.error("Unknown event: {}".format(args.event))
            else:
                self._event_handlers[args.event](cli_args)

        if self.send_heartbeats:
            self._heartbeat(cli_args)

    def _preopen(self, cli_args: list) -> None:
        """Handle terminal creation"""
        pass

    def _preexec(self, cli_args: list) -> None:
        """Send event containing command execution data"""
        args, unknown_args = parser_preexec.parse_known_args(cli_args)

        process = self._terminal_sessions[args.pid]
        event_data = {
            'command': args.command,
            'path': args.path,
            'shell': args.shell,
            'exit_code': 'unknown',
            'session_id': process.unique_id
        }
        process.event = self._insert_event(data=event_data,
                                           timestamp=args.timestamp)

    def _precmd(self, cli_args: list) -> None:
        """Update the stored event with duration and exit_code"""
        args, unknown_args = parser_precmd.parse_known_args(cli_args)
        process = self._terminal_sessions[args.pid]

        if process.event is None:
            return

        event_data = process.event.data

        # Calculate time delta between preexec and precmd
        timestamp = process.event.timestamp
        cur_time = args.timestamp
        time_delta = cur_time - timestamp

        event_data['exit_code'] = args.exit_code

        self._insert_event(data=event_data,
                           id=process.event.id,
                           timestamp=timestamp,
                           duration=time_delta)
        process.event = None

    def _preclose(self, args: argparse.Namespace, args_raw: list) -> None:
        """Remove pid and related data from terminal_processes_data"""
        args, unknown_args = parser_preclose.parse_known_args(cli_args)
        self._terminal_sessions.pop(args.pid)

    def _heartbeat(self, cli_args: list) -> None:
        """Send heartbeat to activity bucket"""
        args, unknown_args = parser_heartbeat.parse_known_args(cli_args)
        process = self._terminal_sessions[args.pid]

        event_data = {
            'session_id': process.unique_id,
            'shell': args.shell,
            'path': args.path
        }
        event = Event(data=event_data, timestamp=args.timestamp)

        inserted_heartbeat = self._client.heartbeat(
            self._buckets['activity']['id'],
            event,
            pulsetime=self.pulsetime,
            queued=True)

        if inserted_heartbeat and inserted_heartbeat.id:
            logger.debug('Successfully sent heartbeat')

    def _insert_event(self, *args, **kwargs) -> Event:
        """Send event to the aw-server"""
        event = Event(*args, **kwargs)
        inserted_event = self._client.insert_event(
            self._buckets['commands']['id'], event)

        # aw-server assigned the event an id
        assert inserted_event.id is not None
        logger.debug("Successfully sent event")

        return inserted_event
Пример #9
0

client = ActivityWatchClient("aw-test-client", testing=True)
client.connect()

bucket_name = "test-bucket"
bucket_etype = "test"
# Delete bucket before creating it, and handle error if it doesn't already exist
try:
    client.delete_bucket(bucket_name)
except HTTPError as e:
    pass
client.create_bucket(bucket_name, bucket_etype)

e1 = create_unique_event()
client.insert_event(bucket_name, e1)

print("Getting events")
events = client.get_events(bucket_name)

print("Asserting events")
assert events[0]['data']['label'] == e1['data']['label']

print("Getting eventcount")
eventcount = client.get_eventcount(bucket_name)
assert eventcount == 1

print("Getting bucket")
buckets = client.get_buckets()
print("Asserting bucket")
assert bucket_name in buckets