Skip to content

Commit

Permalink
New release 0.1.0 (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
Grazfather committed Sep 27, 2019
1 parent 8cd204b commit 7aa90b7
Show file tree
Hide file tree
Showing 45 changed files with 2,120 additions and 296 deletions.
55 changes: 55 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
build:
docker:
- image: circleci/python:3.6.1

# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/postgres:9.4

working_directory: ~/repo

steps:
- checkout

# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "requirements.txt" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-

- run:
name: install dependencies
command: |
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
- save_cache:
paths:
- ./venv
key: v1-dependencies-{{ checksum "requirements.txt" }}

- run:
name: run tests
command: |
. venv/bin/activate
python runtests.py
- run:
name: lint
command: |
. venv/bin/activate
pylint **/*.py -E
pylint **/*.py --exit-zero
- store_artifacts:
path: test-reports
destination: test-reports
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.git
.venv
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*.pyc
config.json
config_savelink.json
config_solvetracker.json
*.bin
*.log
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Changelog
All notable changes to this project will be kept in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [0.1.0] - 2019-09-10
Initial release
10 changes: 7 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
FROM python:3

# Bundle app source
COPY . /src/
WORKDIR /src/
WORKDIR /src

# Copy requirements
COPY ./requirements.txt /src

# Install requirements
RUN pip install --no-cache-dir -r requirements.txt

# Copy rest of source
COPY . /src

CMD ["python", "run.py"]
23 changes: 19 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
PWD = $(shell pwd)

image:
build:
docker build . -t otabot

lint:
image:
docker images | grep otabot || docker build . -t otabot

lint: image
docker run --rm -v ${PWD}/:/src/ otabot pylint **/*.py -E

run: image
checklint: image
docker run --rm -v ${PWD}/:/src/ otabot pylint **/*.py --exit-zero

run: build
docker run --rm -it otabot

runlocal:
runlocal: image
docker run --rm -it -v ${PWD}/:/src/ otabot

test:
docker run --rm -v ${PWD}/:/src/ otabot python3 runtests.py

background: image
docker run --rm -d --name otabot otabot

stop:
docker stop otabot
45 changes: 45 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,48 @@ Example:
3. Update the templates in `templates` according to your preferences (or go with the default ones).
4. Make sure that there's a `_posts` and `_stats` folder in your git repository.
4. You should be good to go now and git support should be active on the next startup. You can now use the `postsolves` command to push blog posts with the current solve status to git.


## Using Link saver

1. Setup a github repo with jekyll and staticman (e.g. https://github.com/ujjwal96/links).
2. Copy `config_savelink.json.template` to `config_savelink.json`.
3. Configure the git repo and branch to be used.
4. Add the decrypted staticman-token used in `staticman.yml` in the config.
5. Add a link to your repo, so people can look it up via `showlinkurl`

Example:
```
{
"git_repo": "reponame/links",
"git_branch": "gh-pages",
"staticman-token": "9d837771-945a-489d-cd80-13abcdefa112",
"allowed_users": [],
"repo_link_url": "https://reponame.github.io/links/"
}
```

## Archive reminder

To enable archive reminders set an offset (in hours) in `config.json` for `archive_ctf_reminder_offset`. Clear or remove the setting to disable reminder handling.

If active, the bot will create a reminder for every bot admin on `!endctf` to inform him, when the ctf was finished for the specified time and it should be archived.

Example (for being reminded one week after the ctf has finished):
```
{
...
"archive_ctf_reminder_offset" : "168"
}
```

## Log command deletion

To enable logging of deleting messages containing specific keywords, set `delete_watch_keywords` in `config.json` to a comma separated list of keywords.
Clear or remove the setting to disable deletion logging.

Example
```
{
"delete_watch_keywords" : "workon, reload, endctf"
}
31 changes: 14 additions & 17 deletions addons/syscalls/syscallinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def __init__(self, filename):

self.parse_table(filename)

def getEntryDict(self, parts, identifiers):
def get_entry_dict(self, parts, identifiers):
entry = collections.OrderedDict()

for i in range(len(parts)):
Expand All @@ -33,23 +33,20 @@ def parse_table(self, filename):

for line in lines[1:]:
parts = line.split("\t")
self.entries[parts[1]] = self.getEntryDict(
self.entries[parts[1]] = self.get_entry_dict(
line.split("\t"), identifiers)

def getEntryByID(self, idx):
def get_entry_by_id(self, idx):
for entry in self.entries:
if self.entries[entry]["#"] == str(idx):
return self.entries[entry]

return None

def getEntryByName(self, name):
if name in self.entries:
return self.entries[name]
def get_entry_by_name(self, name):
return self.entries.get(name)

return None

def getInfoMessage(self, entry):
def get_info_message(self, entry):
if entry:
msg = ""

Expand All @@ -60,13 +57,13 @@ def getInfoMessage(self, entry):

return None

def getInfoMessageByID(self, idx):
entry = self.getEntryByID(idx)
return self.getInfoMessage(entry)
def get_info_message_by_id(self, idx):
entry = self.get_entry_by_id(idx)
return self.get_info_message(entry)

def getInfoMessageByName(self, name):
entry = self.getEntryByName(name)
return self.getInfoMessage(entry)
def get_info_message_by_name(self, name):
entry = self.get_entry_by_name(name)
return self.get_info_message(entry)


class SyscallInfo:
Expand All @@ -79,10 +76,10 @@ def __init__(self, basedir):

self.tables[table] = SyscallTable(filename)

def getAvailableArchitectures(self):
def get_available_architectures(self):
return self.tables.keys()

def getArch(self, arch):
def get_arch(self, arch):
if arch in self.tables:
return self.tables[arch]

Expand Down
2 changes: 2 additions & 0 deletions bottypes/challenge.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ class Challenge:
def __init__(self, ctf_channel_id, channel_id, name, category):
"""
An object representation of an ongoing challenge.
ctf_channel_id : The slack id for the associated parent ctf channel
channel_id : The slack id for the associated channel
name : The name of the challenge
category : The category of the challenge
"""

self.channel_id = channel_id
Expand Down
8 changes: 5 additions & 3 deletions bottypes/command.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from abc import ABC, abstractmethod
from abc import ABC


class Command(ABC):
"""Defines the command interface."""

def __init__(self): pass
def __init__(self):
pass

@classmethod
def execute(cls, slack_client, args, channel_id, user, user_is_admin): pass
def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin):
pass
2 changes: 1 addition & 1 deletion bottypes/ctf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def __init__(self, channel_id, name, long_name):
self.challenges = []
self.cred_user = ""
self.cred_pw = ""
self.cred_url = ""
self.long_name = long_name
self.finished = False
self.finished_on = 0

def add_challenge(self, challenge):
"""
Expand Down
3 changes: 1 addition & 2 deletions bottypes/invalid_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ class InvalidCommand(Exception):
The message should be the usage for that command.
"""

def __init__(self, message):
self.message = message
pass
3 changes: 1 addition & 2 deletions bottypes/invalid_console_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ class InvalidConsoleCommand(Exception):
The message should be the usage for that command.
"""

def __init__(self, message):
self.message = message
pass
4 changes: 3 additions & 1 deletion config.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
"send_help_as_dm" : "1",
"admin_users" : [],
"auto_invite" : [],
"wolfram_app_id" : ""
"wolfram_app_id" : "",
"archive_ctf_reminder_offset" : "168",
"delete_watch_keywords" : ""
}
7 changes: 7 additions & 0 deletions config_savelink.json.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"git_repo": "user/repo",
"git_branch": "master",
"staticman-token": "",
"allowed_users": [],
"repo_link_url": ""
}
3 changes: 2 additions & 1 deletion handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"syscalls_handler",
"bot_handler",
"admin_handler",
"wolfram_handler"
"wolfram_handler",
"linksave_handler"
]
30 changes: 14 additions & 16 deletions handlers/admin_handler.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import re

from bottypes.command import *
from bottypes.command_descriptor import *
from bottypes.invalid_command import *
import handlers.handler_factory as handler_factory
from handlers.base_handler import *
from addons.syscalls.syscallinfo import *
from util.util import *
from bottypes.command import Command
from bottypes.command_descriptor import CommandDesc
from bottypes.invalid_command import InvalidCommand
from handlers import handler_factory
from handlers.base_handler import BaseHandler
from util.util import (get_display_name_from_user, parse_user_id,
resolve_user_by_user_id)


class ShowAdminsCommand(Command):
"""Shows list of users in the admin user group."""

@classmethod
def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin):
"""Execute the ShowAdmins command."""

admin_users = handler_factory.botserver.get_config_option("admin_users")
Expand All @@ -26,7 +24,7 @@ def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
user_object = slack_wrapper.get_member(admin_id)

if user_object['ok']:
response += "*{}* ({})\n".format(user_object['user']['name'], admin_id)
response += "*{}* ({})\n".format(get_display_name_from_user(user_object["user"]), admin_id)

response += "==================================="

Expand All @@ -46,7 +44,7 @@ class AddAdminCommand(Command):
"""Add a user to the admin user group."""

@classmethod
def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin):
"""Execute the AddAdmin command."""
user_object = resolve_user_by_user_id(slack_wrapper, args[0])

Expand All @@ -72,7 +70,7 @@ class RemoveAdminCommand(Command):
"""Remove a user from the admin user group."""

@classmethod
def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin):
"""Execute the RemoveAdmin command."""
user = parse_user_id(args[0])

Expand All @@ -93,7 +91,7 @@ class AsCommand(Command):
"""Execute a command as another user."""

@classmethod
def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
def execute(cls, slack_wrapper, args, timestamp, channel_id, user_id, user_is_admin):
"""Execute the As command."""
dest_user = args[0].lower()
dest_command = args[1].lower().lstrip("!")
Expand All @@ -106,8 +104,8 @@ def execute(cls, slack_wrapper, args, channel_id, user_id, user_is_admin):
dest_user_id = user_obj['user']['id']

# Redirecting command execution to handler factory
handler_factory.process_command(slack_wrapper, dest_command, [
dest_command] + dest_arguments, channel_id, dest_user_id, user_is_admin)
handler_factory.process_command(slack_wrapper, dest_command,
[dest_command] + dest_arguments, timestamp, channel_id, dest_user_id, user_is_admin)
else:
raise InvalidCommand("You have to specify a valid user (use @-notation).")

Expand Down
Loading

0 comments on commit 7aa90b7

Please sign in to comment.