diff --git a/api.rst b/api.rst index 4f42b97..d230f5e 100644 --- a/api.rst +++ b/api.rst @@ -1,17 +1,20 @@ -✓ GET /api/ping -✓ GET /api/auth-token -✓ GET /api/verify-auth -- returns 200 or 401 depend on validity of the provided auth -✓ GET /api/projects -- return project summaries -- POST /api/projects -- create a new project -* GET /api/project/ -- return detailed project record (include steps) -- GET /api/project//active -- return detailed information about all currently running runs -✓ GET /api/project//versions -- list the versions of this project that have been built -- GET /api/project// -- return detailed step information (include runs) -* POST /api/project///run/ -- kick off a run -- GET /api/project///run/ -- return detailed run information +✓ GET /api/ping -- returns "pong" +✓ POST /api/auth-token -- create an return an auth token given {"username": "...", "password": "..."} +✓ GET /api/verify-auth -- returns 200 or 401 depend on validity of the provided auth (auth ping) +✓ GET /api/projects -- return project summaries +- POST /api/projects -- create a new project +- GET /api/project/ -- TODO +- GET /api/project//runs -- list summary information for all runs +- GET /api/project//runs/active -- list summary information about all currently active runs +- GET /api/project//runs/ -- list detailed information about a specific run +✓ GET /api/project//versions -- list the versions of this project that have been built +* GET /api/project//version/ -- return detailed project definition (include steps) at a specific version +- GET /api/project//step/ -- return detailed step information (include runs) +* POST /api/project//step//run/ -- kick off a run Legend: ✓ implemented with passing tests * implemented, needs testing - not implemented + M missing (not even stubbed out) diff --git a/src/main/nim/strawbosspkg/server.nim b/src/main/nim/strawbosspkg/server.nim index adc7011..bc8b53a 100644 --- a/src/main/nim/strawbosspkg/server.nim +++ b/src/main/nim/strawbosspkg/server.nim @@ -29,15 +29,7 @@ proc newSession*(user: UserRef): Session = expires: daysForward(7).toTime()) proc toJWT*(cfg: StrawBossConfig, session: Session): string = -# result = toJWT(%* { -# "header": { -# "alg": "HS256", -# "typ": "JWT" }, -# "claims": { -# "sub": session.user.name, -# "iat": session.issuedAt.toSeconds().int, -# "exp": session.expires.toSeconds().int } }) - + ## Make a JST token for this session. var jwt = JWT( header: JOSEHeader(alg: HS256, typ: "jwt"), claims: toClaims(%*{ @@ -49,6 +41,7 @@ proc toJWT*(cfg: StrawBossConfig, session: Session): string = result = $jwt proc fromJWT*(cfg: StrawBossConfig, strTok: string): Session = + ## Validate a given JWT and extract the session data. let jwt = toJWT(strTok) var secret = cfg.authSecret if not jwt.verify(secret): raiseEx "Unable to verify auth token." @@ -65,6 +58,7 @@ proc fromJWT*(cfg: StrawBossConfig, strTok: string): Session = expires: fromSeconds(jwt.claims["exp"].node.num)) proc extractSession(cfg: StrawBossConfig, request: Request): Session = + ## Helper to extract a session from a reqest. # Find the auth header if not request.headers.hasKey("Authorization"): @@ -98,6 +92,9 @@ proc validatePwd*(u: UserRef, givenPwd: string): bool = result = compare(u.hashedPwd, hash(givenPwd, salt)) proc makeAuthToken*(cfg: StrawBossConfig, uname, pwd: string): string = + ## Given a username and pwd, validate the combination and generate a JWT + ## token string. + if uname == nil or pwd == nil: raiseEx "fields 'username' and 'password' required" @@ -111,6 +108,12 @@ proc makeAuthToken*(cfg: StrawBossConfig, uname, pwd: string): string = result = toJWT(cfg, newSession(user)) template checkAuth() = + ## Check this request for authentication and authorization information. + ## Injects two variables into the running context: the session and authed: + ## true if the request is authorized, false otherwise. If the request is not + ## authorized, this template sets up the 401 response correctly. The calling + ## context needs only to return from the route. + var session {.inject.}: Session var authed {.inject.} = false @@ -164,6 +167,7 @@ proc start*(cfg: StrawBossConfig): void = checkAuth(); if not authed: return true + # TODO resp(Http501, makeJsonResp(Http501), JSON) get "/project/@projectName/versions": @@ -186,7 +190,7 @@ proc start*(cfg: StrawBossConfig): void = resp($(%(versions)), JSON) - get "/project/@projectName/@version?": + get "/project/@projectName/version/@version?": ## Get a detailed project record including step definitions (ProjectConfig). checkAuth(); if not authed: return true @@ -222,28 +226,55 @@ proc start*(cfg: StrawBossConfig): void = cachedFilePath & "\n\t Reason: " & getCurrentExceptionMsg() resp(Http500, makeJsonResp(Http500, "could not read cached project configuration"), JSON) - get "/api/project/@projectName/active": + get "/project/@projectName": + ## TBD + + checkAuth(); if not authed: return true + + # TODO + resp(Http501, makeJsonResp(Http501), JSON) + + get "/project/@projectName/runs": + ## List all runs + + checkAuth(); if not authed: return true + + # TODO + resp(Http501, makeJsonResp(Http501), JSON) + + get "/project/@projectName/runs/active": ## List all currently active runs checkAuth(); if not authed: return true + # TODO resp(Http501, makeJsonResp(Http501), JSON) - get "/api/project/@projectName/@stepName": + get "/project/@projectName/runs/@runId": + ## Details for a specific run + + checkAuth(); if not authed: return true + + # TODO + resp(Http501, makeJsonResp(Http501), JSON) + + get "/project/@projectName/step/@stepName": ## Get step details including runs. checkAuth(); if not authed: return true + # TODO resp(Http501, makeJsonResp(Http501), JSON) - get "/api/project/@projectName/@stepName/run/@buildRef": + get "/project/@projectName/step/@stepName/run/@buildRef": ## Get detailed information about a run checkAuth(); if not authed: return true + # TODO resp(Http501, makeJsonResp(Http501), JSON) - post "/project/@projectName/@stepName/run/@buildRef?": + post "/project/@projectName/step/@stepName/run/@buildRef?": # Kick off a run checkAuth(); if not authed: return true