diff --git a/TODO.txt b/TODO.txt index 8de8e8b..b05874f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -11,7 +11,7 @@ Key: Milestone: v0.1.1 ----------------- -[ ] Abstract user-interactive authentication +[x] Abstract user-interactive authentication [ ] Abstract /email/requestToken and /msidsn/requestToken [ ] User registration diff --git a/src/Matrix.c b/src/Matrix.c index 9d350c4..0db2193 100644 --- a/src/Matrix.c +++ b/src/Matrix.c @@ -299,3 +299,108 @@ MatrixErrorCreate(MatrixError errorArg) return errorObj; } + +static HashMap * +BuildDummyFlow(void) +{ + HashMap *response = HashMapCreate(); + HashMap *dummyFlow = HashMapCreate(); + Array *stages = ArrayCreate(); + Array *flows = ArrayCreate(); + + ArrayAdd(stages, + JsonValueString(UtilStringDuplicate("m.login.dummy"))); + HashMapSet(dummyFlow, "stages", JsonValueArray(stages)); + ArrayAdd(flows, JsonValueObject(dummyFlow)); + + HashMapSet(response, "flows", JsonValueArray(flows)); + HashMapSet(response, "params", + JsonValueObject(HashMapCreate())); + + return response; +} + +HashMap * +MatrixUserInteractiveAuth(HttpServerContext * context, Db * db, + HashMap * request) +{ + JsonValue *auth; + JsonValue *type; + JsonValue *session; + + HashMap *authObj; + char *typeStr; + char *sessionStr; + + DbRef *ref; + + auth = HashMapGet(request, "auth"); + if (!auth) + { + HashMap *response = NULL; + HashMap *persist; + char *session = UtilRandomString(24); + + ref = DbCreate(db, 2, "user_interactive", session); + persist = DbJson(ref); + + HashMapSet(persist, "created", + JsonValueInteger(UtilServerTs())); + HashMapSet(persist, "completed", JsonValueBoolean(0)); + + DbUnlock(db, ref); + + HttpResponseStatus(context, HTTP_UNAUTHORIZED); + response = BuildDummyFlow(); + + HashMapSet(response, "session", JsonValueString(session)); + + return response; + } + + if (JsonValueType(auth) != JSON_OBJECT) + { + HttpResponseStatus(context, HTTP_BAD_REQUEST); + return MatrixErrorCreate(M_BAD_JSON); + } + + authObj = JsonValueAsObject(auth); + type = HashMapGet(authObj, "type"); + session = HashMapGet(authObj, "session"); + + if (!type || JsonValueType(type) != JSON_STRING) + { + HttpResponseStatus(context, HTTP_BAD_REQUEST); + return MatrixErrorCreate(M_BAD_JSON); + } + + if (!session || JsonValueType(session) != JSON_STRING) + { + HttpResponseStatus(context, HTTP_UNAUTHORIZED); + return BuildDummyFlow(); + } + + typeStr = JsonValueAsString(session); + sessionStr = JsonValueAsString(session); + + if (strcmp(typeStr, "m.login.dummy") != 0) + { + HttpResponseStatus(context, HTTP_BAD_REQUEST); + return MatrixErrorCreate(M_INVALID_PARAM); + } + + /* Check to see if session exists */ + ref = DbLock(db, 2, "user_interactive", sessionStr); + + if (!ref) + { + HttpResponseStatus(context, HTTP_BAD_REQUEST); + return MatrixErrorCreate(M_UNKNOWN); + } + + /* We only need to know that it exists. */ + DbUnlock(db, ref); + DbDelete(db, 2, "user_interactive", sessionStr); + + return NULL; /* All good, auth successful */ +} diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index 43e709c..a6630f1 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -30,26 +30,6 @@ #include #include -static HashMap * -BuildDummyFlow(void) -{ - HashMap *response = HashMapCreate(); - HashMap *dummyFlow = HashMapCreate(); - Array *stages = ArrayCreate(); - Array *flows = ArrayCreate(); - - ArrayAdd(stages, - JsonValueString(UtilStringDuplicate("m.login.dummy"))); - HashMapSet(dummyFlow, "stages", JsonValueArray(stages)); - ArrayAdd(flows, JsonValueObject(dummyFlow)); - - HashMapSet(response, "flows", JsonValueArray(flows)); - HashMapSet(response, "params", - JsonValueObject(HashMapCreate())); - - return response; -} - ROUTE_IMPL(RouteRegister, args) { HashMap *request = NULL; @@ -57,32 +37,14 @@ ROUTE_IMPL(RouteRegister, args) char *pathPart = NULL; - DbRef *ref; - HashMap *persist; - if (MATRIX_PATH_PARTS(args->path) == 0) { - JsonValue *auth = NULL; - - HashMap *authObj = JsonValueAsObject(auth); - JsonValue *type = HashMapGet(authObj, "type"); - JsonValue *session = HashMapGet(authObj, "session"); - - char *typeStr; - char *sessionStr; - if (HttpRequestMethodGet(args->context) != HTTP_POST) { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); return MatrixErrorCreate(M_UNRECOGNIZED); } - if (!(args->matrixArgs->config->flags & TELODENDRIA_REGISTRATION)) - { - HttpResponseStatus(args->context, HTTP_FORBIDDEN); - return MatrixErrorCreate(M_FORBIDDEN); - } - request = JsonDecode(HttpStream(args->context)); if (!request) { @@ -90,77 +52,19 @@ ROUTE_IMPL(RouteRegister, args) return MatrixErrorCreate(M_NOT_JSON); } - auth = HashMapGet(request, "auth"); - if (!auth) + if (!(args->matrixArgs->config->flags & TELODENDRIA_REGISTRATION)) { - char *session = UtilRandomString(24); - - ref = DbCreate(args->matrixArgs->db, 2, - "user_interactive", session); - persist = DbJson(ref); - - HashMapSet(persist, "created", - JsonValueInteger(UtilServerTs())); - HashMapSet(persist, "completed", JsonValueBoolean(0)); - - DbUnlock(args->matrixArgs->db, ref); - - HttpResponseStatus(args->context, HTTP_UNAUTHORIZED); - response = BuildDummyFlow(); - - HashMapSet(response, "session", JsonValueString(session)); - + HttpResponseStatus(args->context, HTTP_FORBIDDEN); + response = MatrixErrorCreate(M_FORBIDDEN); goto finish; } - if (JsonValueType(auth) != JSON_OBJECT) + response = MatrixUserInteractiveAuth(args->context, args->matrixArgs->db, request); + if (response) { - HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_BAD_JSON); goto finish; } - if (!type || JsonValueType(type) != JSON_STRING) - { - HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_BAD_JSON); - goto finish; - } - - if (!session || JsonValueType(session) != JSON_STRING) - { - HttpResponseStatus(args->context, HTTP_UNAUTHORIZED); - response = BuildDummyFlow(); - goto finish; - } - - typeStr = JsonValueAsString(session); - sessionStr = JsonValueAsString(session); - - if (strcmp(typeStr, "m.login.dummy") != 0) - { - HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_INVALID_PARAM); - goto finish; - } - - /* Check to see if session exists */ - ref = DbLock(args->matrixArgs->db, 2, - "user_interactive", sessionStr); - - if (!ref) - { - HttpResponseStatus(args->context, HTTP_BAD_REQUEST); - response = MatrixErrorCreate(M_UNKNOWN); - goto finish; - } - - /* We only need to know that it exists. */ - DbUnlock(args->matrixArgs->db, ref); - DbDelete(args->matrixArgs->db, 2, - "user_interactive", sessionStr); - - /* TODO: Abstract all the above logic out to a function */ /* TODO: Register new user here */ finish: diff --git a/src/include/Matrix.h b/src/include/Matrix.h index 907aa58..fbfb5d7 100644 --- a/src/include/Matrix.h +++ b/src/include/Matrix.h @@ -80,4 +80,7 @@ extern void extern HashMap * MatrixErrorCreate(MatrixError); +extern HashMap * + MatrixUserInteractiveAuth(HttpServerContext *, Db *, HashMap *); + #endif