diff --git a/.gitignore b/.gitignore index e075d71..8ddde79 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__/ db.json +namensliste.csv *.egg-info diff --git a/config.ini b/config.ini index aa4a5ec..ebec123 100644 --- a/config.ini +++ b/config.ini @@ -1,4 +1,10 @@ [global] + # Persistent file for storage of times, in .json format. # Remove or leave empty for temporary (/tmp/ftracker-db.json) storage db_file = db.json + +# List of people to be allowed, in .csv format (comma, no delimiters) +# Col1: First Name(s), Col2: Last Name(s), Col3 (optional): EMail +# Remove or leave empty for no check +name_file = namensliste.csv diff --git a/ftracker/config.py b/ftracker/config.py index aa4099e..fc88dc6 100644 --- a/ftracker/config.py +++ b/ftracker/config.py @@ -1,20 +1,31 @@ import sys, os from configparser import ConfigParser -def findConfigFile(): - if len(sys.argv) > 1: - return sys.argv[1] - elif os.path.isfile('config.ini'): - return 'config.ini' - elif os.path.isfile('/etc/ftracker/config.ini'): - return '/etc/ftracker/config.ini' - else: - return None +class Config: -configfile = findConfigFile() + def __init__(self): -if configfile: - config = ConfigParser() - config.read(configfile) -else: - config = None + def findConfigFile(): + if len(sys.argv) > 1: + return sys.argv[1] + elif os.path.isfile('config.ini'): + return 'config.ini' + elif os.path.isfile('/etc/ftracker/config.ini'): + return '/etc/ftracker/config.ini' + else: + return None + + configfile = findConfigFile() + + if configfile: + self.config = ConfigParser() + self.config.read(configfile) + else: + raise Exception("No config file found") + + if not 'global' in self.config: + raise Exception("No 'global' section found in config file") + + + def __getitem__(self, key): + return self.config['global'].get(key) diff --git a/ftracker/core.py b/ftracker/core.py index 960de83..a89df6b 100644 --- a/ftracker/core.py +++ b/ftracker/core.py @@ -2,16 +2,18 @@ import json from datetime import datetime from slugify import slugify -from .config import config -if not config: - print('No configuration file found.') - exit() +from .config import Config +config = Config() from tinydb import TinyDB -dbfile = config['global'].get('db_file') or '/tmp/ftracker-db.json' +dbfile = config['db_file'] or '/tmp/ftracker-db.json' db = TinyDB(dbfile, indent=4) -# TODO: Load name list if needed + + +from .namelist import NameList +namefile = config['name_file'] or None +namelist = NameList(namefile) from flask import Flask, request @@ -37,10 +39,11 @@ def post_time(): if not data['agreetoguidelines']: return "Error: Didn't agree to guidelines.", 406 - - name = slugify(data['name']) + if not name in namelist: + return "Error: Name not in permitted list.", 401 + now = datetime.utcnow() db.insert({ 'name': name, diff --git a/ftracker/namelist.py b/ftracker/namelist.py new file mode 100644 index 0000000..5691338 --- /dev/null +++ b/ftracker/namelist.py @@ -0,0 +1,40 @@ +import csv +from slugify import slugify + +class NameList: + + def __init__(self, namefile): + + print('(Re)loading name list') + + if not namefile: + self.names = None + return + + self.namefile = namefile + self.names = {} + + with open(namefile) as f: + + reader = csv.reader(f) + for line in reader: + + name = f"{line[0]} {line[1]}" + slug = slugify(name) + email = line[2] if len(line) > 2 else None + + self.names[slug] = {'email': email} + + def __contains__(self, val): + # Don't check if there's no list + if self.names == None: + return true; + + contained = val in self.names + + # Reload name list if name is unknown and recheck + if not contained: + self.__init__(self.namefile) + contained = val in self.names + + return contained