diff --git a/devel/devel-server.py b/devel/devel-server.py index af0679b..041ba7b 100755 --- a/devel/devel-server.py +++ b/devel/devel-server.py @@ -28,6 +28,16 @@ def get_seed(request): else: return int(seedstr) + +def get_puzzle(request): + seed = get_seed(request) + category = request.match_info.get("category") + points = int(request.match_info.get("points")) + filename = request.match_info.get("filename") + cat = moth.Category(request.app["puzzles_dir"].joinpath(category), seed) + puzzle = cat.puzzle(points) + return puzzle + async def handle_puzzlelist(request): seed = get_seed(request) @@ -87,6 +97,16 @@ async def handle_puzzlefile(request): content_type=content_type, ) + +async def handle_answer(request): + seed = get_seed(request) + category = request.match_info.get("category") + points = int(request.match_info.get("points")) + filename = request.match_info.get("filename") + cat = moth.Category(request.app["puzzles_dir"].joinpath(category), seed) + puzzle = cat.puzzle(points) + + async def handle_mothballer(request): seed = get_seed(request) @@ -113,19 +133,37 @@ async def handle_index(request): seed = random.getrandbits(32) body = """ -
- You need to provide the contest seed in the URL. - If you don't have a contest seed in mind, - why not try {seed}? + Pick a seed:
+- If you are chaotic, - you could even take your chances with a - random seed for every HTTP request. - This means generated files will get a different seed than the puzzle itself! + Puzzles can be generated from Python code: these puzzles can use a random number generator if they want. + The seed is used to create these random numbers. +
+ ++ We like to make a new seed for every contest, + and re-use that seed whenever we regenerate a category during an event + (say to fix a bug). + By using the same seed, + we make sure that all the dynamically-generated puzzles have the same values + in any new packages we build.
@@ -140,12 +178,8 @@ async def handle_static(request): themes = request.app["theme_dir"] fn = request.match_info.get("filename") if not fn: - for fn in ("puzzle-list.html", "index.html"): - path = themes.joinpath(fn) - if path.exists(): - break - else: - path = themes.joinpath(fn) + fn = "index.html" + path = themes.joinpath(fn) return web.FileResponse(path) @@ -182,7 +216,7 @@ if __name__ == '__main__': app["puzzles_dir"] = pathlib.Path(args.puzzles) app["theme_dir"] = pathlib.Path(args.theme) app.router.add_route("GET", "/", handle_index) - app.router.add_route("GET", "/{seed}/puzzles.json", handle_puzzlelist) + app.router.add_route("*", "/{seed}/puzzles.json", handle_puzzlelist) app.router.add_route("GET", "/{seed}/content/{category}/{points}/puzzle.json", handle_puzzle) app.router.add_route("GET", "/{seed}/content/{category}/{points}/{filename}", handle_puzzlefile) app.router.add_route("GET", "/{seed}/mothballer/{category}", handle_mothballer) diff --git a/src/handlers.go b/src/handlers.go index 89643b2..950d45a 100644 --- a/src/handlers.go +++ b/src/handlers.go @@ -175,6 +175,12 @@ func (ctx *Instance) answerHandler(w http.ResponseWriter, req *http.Request) { } func (ctx *Instance) puzzlesHandler(w http.ResponseWriter, req *http.Request) { + teamid := req.FormValue("id") + if _, err := ctx.TeamName(teamid); err != nil { + http.Error(w, "Unauthorized: must provide team ID", http.StatusUnauthorized) + return + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(ctx.jPuzzleList) @@ -273,13 +279,7 @@ func (ctx *Instance) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { w: wOrig, statusCode: new(int), } - w.Header().Set("WWW-Authenticate", "Basic") - _, password, _ := r.BasicAuth() - if password != ctx.Password { - http.Error(w, "Authentication Required", 401) - } else { - ctx.mux.ServeHTTP(w, r) - } + ctx.mux.ServeHTTP(w, r) log.Printf( "%s %s %s %d\n", r.RemoteAddr, diff --git a/src/instance.go b/src/instance.go index c226869..bd89e5d 100644 --- a/src/instance.go +++ b/src/instance.go @@ -19,7 +19,6 @@ type Instance struct { MothballDir string StateDir string ResourcesDir string - Password string Categories map[string]*Mothball update chan bool jPuzzleList []byte @@ -27,13 +26,12 @@ type Instance struct { mux *http.ServeMux } -func NewInstance(base, mothballDir, stateDir, resourcesDir, password string) (*Instance, error) { +func NewInstance(base, mothballDir, stateDir, resourcesDir string) (*Instance, error) { ctx := &Instance{ Base: strings.TrimRight(base, "/"), MothballDir: mothballDir, StateDir: stateDir, ResourcesDir: resourcesDir, - Password: password, Categories: map[string]*Mothball{}, update: make(chan bool, 10), mux: http.NewServeMux(), diff --git a/src/mothd.go b/src/mothd.go index b53bd78..46b7d42 100644 --- a/src/mothd.go +++ b/src/mothd.go @@ -37,11 +37,6 @@ func main() { "/theme", "Path to static theme resources (HTML, images, css, ...)", ) - password := flag.String( - "password", - "sesame", - "Pass Word (in the 1920s sense) to view the site. Not a secure passphrase.", - ) maintenanceInterval := flag.Duration( "maint", 20*time.Second, @@ -58,7 +53,7 @@ func main() { log.Fatal(err) } - ctx, err := NewInstance(*base, *mothballDir, *stateDir, *themeDir, *password) + ctx, err := NewInstance(*base, *mothballDir, *stateDir, *themeDir) if err != nil { log.Fatal(err) } diff --git a/theme/index.html b/theme/index.html index 6a69e85..89bdf48 100644 --- a/theme/index.html +++ b/theme/index.html @@ -2,6 +2,7 @@