From 45dc79e2100d706acb6ce0acc4390b70a4d4fd1e Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Wed, 6 Nov 2013 20:09:21 +0000 Subject: [PATCH] generalise user handling more so that not only signup and login is possible but also password or userdata changes and further administration. --- assets/js/init.js | 2 +- include/application/application.h | 3 + src/application/Makefile.am | 9 ++- .../controller/_process_user_create_args.c | 76 +++++++++++++++++ src/application/controller/_validate_email.c | 58 +++++++++++++ .../controller/_validate_password.c | 46 +++++++++++ .../controller/_validate_password_repeat.c | 46 +++++++++++ src/application/controller/signup/create.c | 66 +++++++++++++++ src/application/controller/user/create.c | 51 ++---------- src/application/controller/user/read.c | 61 ++++++++++++++ src/application/create_user.c | 81 +++++++++++++++++++ src/application/get_user.c | 65 +++++++++++++++ src/application/update_password.c | 74 +++++++++++++++++ src/router/route.c | 8 +- 14 files changed, 599 insertions(+), 47 deletions(-) create mode 100644 src/application/controller/_process_user_create_args.c create mode 100644 src/application/controller/_validate_email.c create mode 100644 src/application/controller/_validate_password.c create mode 100644 src/application/controller/_validate_password_repeat.c create mode 100644 src/application/controller/signup/create.c create mode 100644 src/application/controller/user/read.c create mode 100644 src/application/create_user.c create mode 100644 src/application/get_user.c create mode 100644 src/application/update_password.c diff --git a/assets/js/init.js b/assets/js/init.js index 87269fc..c1a26ab 100644 --- a/assets/js/init.js +++ b/assets/js/init.js @@ -76,7 +76,7 @@ $(document).ready(function() { $("#signup").load("/_signup.html", function (){ $("#signup form").submit(function(event) { event.preventDefault(); - $.post("/user/", + $.post("/signup/", $("#signup form").serialize(), $.proxy(sess.loadUserJSON, sess)); $("#signup").addClass("hide"); diff --git a/include/application/application.h b/include/application/application.h index 9e88acb..561daf6 100644 --- a/include/application/application.h +++ b/include/application/application.h @@ -64,6 +64,9 @@ CLASS(Application) { int applicationLogin(Application, Credential, Session); void applicationLogout(Application, Session); int applicationSignup(Application, Credential, User, Session); +Uuid applicationCreateUser(Application, Credential, User); +User applicationGetUser(Application, Uuid); +int applicationUpdatePassword(Application, Credential, User); Session applicationSessionStart(Application); Session applicationSessionGet(Application, const char *); diff --git a/src/application/Makefile.am b/src/application/Makefile.am index 09cb56f..51ba6e6 100644 --- a/src/application/Makefile.am +++ b/src/application/Makefile.am @@ -5,6 +5,9 @@ APPLICATION = application.c \ login.c \ logout.c \ signup.c \ + get_user.c \ + create_user.c \ + update_password.c \ session_start.c \ session_stop.c \ session_get.c \ @@ -17,7 +20,11 @@ CONTROLLER = controller/authenticate/create.c \ controller/randval/read.c \ controller/sessinfo/read.c \ controller/user/create.c \ - controller/version/read.c + controller/user/read.c \ + controller/signup/create.c \ + controller/version/read.c \ + controller/_validate_password_repeat.c \ + controller/_process_user_create_args.c AM_CFLAGS += -I../../include/ diff --git a/src/application/controller/_process_user_create_args.c b/src/application/controller/_process_user_create_args.c new file mode 100644 index 0000000..a00faf6 --- /dev/null +++ b/src/application/controller/_process_user_create_args.c @@ -0,0 +1,76 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2013 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define _GNU_SOURCE + +#include "hash.h" +#include "user.h" +#include "auth/credential.h" + +#include "utils/memory.h" +#include "commons.h" + +int _controllerValidatePasswordRepeat(char *, size_t, char *, size_t); + + +int +_controllerProcessUserCreateArgs(Hash args, User * user, Credential * cred) +{ + HashValue email = hashGet(args, CSTRA("email")); + HashValue password = hashGet(args, CSTRA("password")); + HashValue pwrepeat = hashGet(args, CSTRA("pwrepeat")); + HashValue firstname = hashGet(args, CSTRA("firstname")); + HashValue surname = hashGet(args, CSTRA("surname")); + + if ( + NULL == email || + NULL == password || + NULL == pwrepeat || + NULL == firstname || + NULL == surname) + { + return FALSE; + } + + if (! _controllerValidatePasswordRepeat( + password->value, + password->nvalue, + pwrepeat->value, + pwrepeat->nvalue)) + { + return FALSE; + } + + *cred = new(Credential, + CRED_PASSWORD, + (char *)(email->value), email->nvalue, + (char *)(password->value), password->nvalue); + + *user = new(User, + (char *)(email->value), email->nvalue, + (char *)(firstname->value), firstname->nvalue, + (char *)(surname->value), surname->nvalue); + + return TRUE; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/controller/_validate_email.c b/src/application/controller/_validate_email.c new file mode 100644 index 0000000..1a0e6bc --- /dev/null +++ b/src/application/controller/_validate_email.c @@ -0,0 +1,58 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2013 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define _GNU_SOURCE + +#include "application/application.h" +#include "session.h" +#include "hash.h" +#include "auth/credential.h" +#include "user.h" + +#include "utils/memory.h" + +User +_controllerCreateUserFromArgs(Hash args) +{ + HashValue email; + HashValue firstname; + HashValue surname; + + email = hashGet(args, CSTRA("email")); + firstname = hashGet(args, CSTRA("firstname")); + surname = hashGet(args, CSTRA("surname")); + + if ( + NULL == email || + NULL == firstname || + NULL == surname) + { + return NULL; + } + + return new(User, + (char *)(email->value), email->nvalue, + (char *)(firstname->value), firstname->nvalue, + (char *)(surname->value), surname->nvalue); +} + +// vim: set ts=4 sw=4: diff --git a/src/application/controller/_validate_password.c b/src/application/controller/_validate_password.c new file mode 100644 index 0000000..e6a30e0 --- /dev/null +++ b/src/application/controller/_validate_password.c @@ -0,0 +1,46 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2013 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "hash.h" +#include "auth/credential.h" + +#include "utils/memory.h" +#include "commons.h" + +int +_controllerValidatePassword( + char * password, + size_t npassword, + char * pwrepeat, + size_t npwrepeat, ) +{ + if ( + password->nvalue != pwrepeat->nvalue || + 0 != memcmp(password->value, pwrepeat->value, password->nvalue)) + { + return FALSE; + } + + return TRUE; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/controller/_validate_password_repeat.c b/src/application/controller/_validate_password_repeat.c new file mode 100644 index 0000000..e2ece39 --- /dev/null +++ b/src/application/controller/_validate_password_repeat.c @@ -0,0 +1,46 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2013 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "hash.h" +#include "auth/credential.h" + +#include "utils/memory.h" +#include "commons.h" + +int +_controllerValidatePasswordRepeat( + char * password, + size_t npassword, + char * pwrepeat, + size_t npwrepeat) +{ + if ( + npassword != npwrepeat || + 0 != memcmp(password, pwrepeat, npassword)) + { + return FALSE; + } + + return TRUE; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/controller/signup/create.c b/src/application/controller/signup/create.c new file mode 100644 index 0000000..3a7642a --- /dev/null +++ b/src/application/controller/signup/create.c @@ -0,0 +1,66 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2013 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define _GNU_SOURCE + +#include "application/application.h" +#include "session.h" +#include "hash.h" +#include "auth/credential.h" +#include "user.h" + +#include "utils/memory.h" + +char * controllerCurrentuserRead(Application, Session, Hash); +int _controllerProcessUserCreateArgs(Hash, User *, Credential *); + + +char * +controllerSignupCreate( + Application application, + Session session, + Hash args) +{ + Credential credential; + User user; + char * response_data; + + _controllerProcessUserCreateArgs(args, &user, &credential); + + if (0 == uuidCompare( + uuidZero, + applicationCreateUser(application, credential, user))) + { + response_data = NULL; + } else { + applicationLogin(application, credential, session); + response_data = controllerCurrentuserRead(application, session, NULL); + } + + delete(credential); + delete(user); + + return response_data; + +} + +// vim: set ts=4 sw=4: diff --git a/src/application/controller/user/create.c b/src/application/controller/user/create.c index 81bcf41..6623b23 100644 --- a/src/application/controller/user/create.c +++ b/src/application/controller/user/create.c @@ -31,6 +31,7 @@ #include "utils/memory.h" char * controllerCurrentuserRead(Application, Session, Hash); +int _controllerProcessUserCreateArgs(Hash, User *, Credential *); char * controllerUserCreate( @@ -38,54 +39,18 @@ controllerUserCreate( Session session, Hash args) { - HashValue email; - HashValue password; - HashValue pwrepeat; - HashValue firstname; - HashValue surname; + Credential credential; + User user; + char * response_data; - Credential credential; - User user; + _controllerProcessUserCreateArgs(args, &user, &credential); - char * response_data; - - email = hashGet(args, CSTRA("email")); - password = hashGet(args, CSTRA("password")); - pwrepeat = hashGet(args, CSTRA("pwrepeat")); - firstname = hashGet(args, CSTRA("firstname")); - surname = hashGet(args, CSTRA("surname")); - - if ( - NULL == email || - NULL == password || - NULL == pwrepeat || - NULL == firstname || - NULL == surname) - { - return NULL; - } - - if ( - password->nvalue != pwrepeat->nvalue || - 0 != memcmp(password->value, pwrepeat->value, password->nvalue)) + if (0 == uuidCompare( + uuidZero, + applicationCreateUser(application, credential, user))) { - return NULL; - } - - credential = new(Credential, - CRED_PASSWORD, - (char *)(email->value), email->nvalue, - (char *)(password->value), password->nvalue); - - user = new(User, - (char *)(email->value), email->nvalue, - (char *)(firstname->value), firstname->nvalue, - (char *)(surname->value), surname->nvalue); - - if (! applicationSignup(application, credential, user, session)) { response_data = NULL; } else { - applicationLogin(application, credential, session); response_data = controllerCurrentuserRead(application, session, NULL); } diff --git a/src/application/controller/user/read.c b/src/application/controller/user/read.c new file mode 100644 index 0000000..5a3fa64 --- /dev/null +++ b/src/application/controller/user/read.c @@ -0,0 +1,61 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2013 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define _GNU_SOURCE + +#include +#include + +#include "class.h" +#include "application/application.h" +#include "session.h" +#include "hash.h" + +#include "utils/memory.h" + + +#define USER_JSON \ + "{\"email\":\"%s\",\"firstname\":\"%s\",\"surname\":\"%s\"}" + +char * +controllerUserRead(Application app, Session sess, Hash args) +{ + char * buffer; + size_t nbuffer; + HashValue id = hashGet(args, CSTRA("id")); + Uuid search = uuidParse(id->value); + User user = applicationGetUser(app, search); + + nbuffer = snprintf(NULL, 0, USER_JSON, + user->email, + user->firstname, + user->surname); + buffer = memMalloc(nbuffer); + nbuffer = sprintf(buffer, USER_JSON, + user->email, + user->firstname, + user->surname); + + return buffer; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/create_user.c b/src/application/create_user.c new file mode 100644 index 0000000..3de9b1f --- /dev/null +++ b/src/application/create_user.c @@ -0,0 +1,81 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include "class.h" +#include "auth.h" +#include "user.h" +#include "uuid.h" +#include "storage/storage.h" +#include "application/application.h" + +#include "interface/serializable.h" +#include "interface/indexable.h" + +#include "utils/memory.h" +#include "commons.h" + +Uuid +applicationCreateUser( + Application this, + Credential cred, + User user) +{ + char * user_serialized; + size_t nuser_serialized; + Uuid index; + + index = indexUuid(user, this->user_namespace); + serialize(user, (unsigned char **)&user_serialized, &nuser_serialized); + + if (SPR_OK != storagePut( + this->users, + (char *)(index->uuid).value, + sizeof((index->uuid).value), + user_serialized, + nuser_serialized)) + { + return uuidZero; + } + + if (! applicationUpdatePassword(this, cred, user)) { + /** + * \todo + * error handling is missing here + */ + storageDelete( + this->users, + (char *)(index->uuid).value, + sizeof((index->uuid).value)); + + return uuidZero; + } + + return index; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/get_user.c b/src/application/get_user.c new file mode 100644 index 0000000..09c9bff --- /dev/null +++ b/src/application/get_user.c @@ -0,0 +1,65 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "class.h" +#include "auth.h" +#include "user.h" +#include "uuid.h" +#include "storage/storage.h" +#include "application/application.h" + +#include "interface/serializable.h" +#include "interface/indexable.h" + +#include "utils/memory.h" +#include "commons.h" + +User +applicationGetUser(Application this, Uuid uuid) +{ + char * user_serialized; + size_t nuser_serialized; + User user = NULL; + + storageGet( + this->users, + (char *)(uuid->uuid).value, + sizeof((uuid->uuid).value), + &user_serialized, + &nuser_serialized); + + if (NULL != user_serialized) { + unserialize( + user, + (unsigned char *)user_serialized, + nuser_serialized); + MEM_FREE(user_serialized); + } + + return user; +} + +// vim: set ts=4 sw=4: diff --git a/src/application/update_password.c b/src/application/update_password.c new file mode 100644 index 0000000..307b374 --- /dev/null +++ b/src/application/update_password.c @@ -0,0 +1,74 @@ +/** + * \file + * + * \author Georg Hopp + * + * \copyright + * Copyright © 2012 Georg Hopp + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define _GNU_SOURCE + +#include +#include +#include + +#include "class.h" +#include "auth.h" +#include "user.h" +#include "storage/storage.h" +#include "application/application.h" + +#include "interface/indexable.h" + +#include "utils/memory.h" +#include "commons.h" + +int +applicationUpdatePassword( + Application this, + Credential cred, + User user) +{ + unsigned char hash_data[SALT_SIZE+HASH_SIZE]; + unsigned char * salt = NULL; + unsigned char * hash = hash_data+SALT_SIZE; + Uuid index; + + index = indexUuid(user, this->user_namespace); + + if (FALSE == hash_pw( + CRED_PWD(cred).pass, + CRED_PWD(cred).npass, + hash, + &salt)) { + return FALSE; + } + + memcpy(hash_data, salt, SALT_SIZE); + MEM_FREE(salt); + + storageUpdate( + this->passwords, + (char *)(index->uuid).value, + sizeof((index->uuid).value), + (char *)hash_data, + SALT_SIZE + HASH_SIZE); + + return TRUE; +} + +// vim: set ts=4 sw=4: diff --git a/src/router/route.c b/src/router/route.c index cb3f2c8..ab207c9 100644 --- a/src/router/route.c +++ b/src/router/route.c @@ -265,8 +265,12 @@ routerRoute( break; } - response = httpResponseJson(response_data, strlen(response_data)); - MEM_FREE(response_data); + if (NULL != response_data) { + response = httpResponseJson(response_data, strlen(response_data)); + MEM_FREE(response_data); + } else { + response = httpResponse404(); + } return response; }