Commit 080add7222b50d7d45594000abcd9ef0d97166ba

Authored by Georg Hopp
1 parent 3300067b

remove specialized load and save from user, add serializable and indexable inter…

…face and make user utilize both and store a user and its credentials keyed by its uuid
... ... @@ -33,6 +33,7 @@
33 33 #include "storage/storage.h"
34 34 #include "session.h"
35 35 #include "user.h"
  36 +#include "uuid.h"
36 37
37 38
38 39 struct randval {
... ... @@ -50,6 +51,12 @@ CLASS(Application) {
50 51
51 52 Storage users;
52 53 Storage passwords;
  54 + Storage roles;
  55 +
  56 + Uuid user_namespace;
  57 +
  58 + Hash roles_user_index;
  59 + Hash roles_resource_index;
53 60
54 61 const char * version;
55 62 };
... ...
... ... @@ -31,9 +31,10 @@
31 31 #include <stdarg.h>
32 32
33 33 #include "class.h"
  34 +#include "uuid.h"
34 35 #include "auth/credential.h"
35 36
36   -typedef int (* fptr_authenticate)(void *, Credential);
  37 +typedef int (* fptr_authenticate)(void *, Credential, Uuid);
37 38
38 39 extern const struct interface i_Auth;
39 40
... ... @@ -42,7 +43,7 @@ struct i_Auth {
42 43 fptr_authenticate authenticate;
43 44 };
44 45
45   -extern int authenticate(void *, Credential);
  46 +extern int authenticate(void *, Credential, Uuid);
46 47
47 48 #endif // __AUTH_INTERFACE_AUTH_H__
48 49
... ...
  1 +/**
  2 + * \file
  3 + * This interface provides only one function at all.
  4 + * indexUuid will generate a uuid to the current object.
  5 + *
  6 + * \todo
  7 + * Maybe merge hashable and indexable. Thus we might get an
  8 + * easy way to exchange the hashing mechanism used for my
  9 + * associative arrays.
  10 + *
  11 + * \author Georg Hopp
  12 + *
  13 + * \copyright
  14 + * Copyright © 2012 Georg Hopp
  15 + *
  16 + * This program is free software: you can redistribute it and/or modify
  17 + * it under the terms of the GNU General Public License as published by
  18 + * the Free Software Foundation, either version 3 of the License, or
  19 + * (at your option) any later version.
  20 + *
  21 + * This program is distributed in the hope that it will be useful,
  22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24 + * GNU General Public License for more details.
  25 + *
  26 + * You should have received a copy of the GNU General Public License
  27 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  28 + */
  29 +
  30 +#ifndef __INDEXABLE_H__
  31 +#define __INDEXABLE_H__
  32 +
  33 +#include "uuid.h"
  34 +
  35 +
  36 +typedef Uuid (* fptr_indexUuid)(void *, Uuid);
  37 +
  38 +extern const struct interface i_Indexable;
  39 +
  40 +struct i_Indexable {
  41 + const struct interface * const _;
  42 + fptr_indexUuid uuid;
  43 +};
  44 +
  45 +extern Uuid indexUuid(void *, Uuid);
  46 +
  47 +#endif // __INDEXABLE_H__
  48 +
  49 +// vim: set ts=4 sw=4:
... ...
  1 +/**
  2 + * \file
  3 + *
  4 + * \author Georg Hopp
  5 + *
  6 + * \copyright
  7 + * Copyright © 2012 Georg Hopp
  8 + *
  9 + * This program is free software: you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation, either version 3 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21 + */
  22 +
  23 +#ifndef __SERIALIZABLE_H__
  24 +#define __SERIALIZABLE_H__
  25 +
  26 +typedef void (* fptr_serialize)(void *, unsigned char **, size_t *);
  27 +typedef void (* fptr_unserialize)(void *, const unsigned char *, size_t);
  28 +
  29 +extern const struct interface i_Serializable;
  30 +
  31 +struct i_Serializable {
  32 + const struct interface * const _;
  33 + fptr_serialize serialize;
  34 + fptr_unserialize unserialize;
  35 +};
  36 +
  37 +extern void serialize(void *, unsigned char **, size_t *);
  38 +extern void unserialize(void *, const unsigned char *, size_t);
  39 +
  40 +#endif // __SERIALIZABLE_H__
  41 +
  42 +// vim: set ts=4 sw=4:
... ...
... ... @@ -10,7 +10,9 @@ TRUTILS = utils/hash.c \
10 10 utils/mime_type.c
11 11
12 12 TRBASESRC = interface/subject.c \
13   - interface/observer.c
  13 + interface/observer.c \
  14 + interface/serializable.c \
  15 + interface/indexable.c
14 16
15 17 TRBASELIBS = class/libclass.la \
16 18 cbuf/libcbuf.la \
... ...
... ... @@ -26,6 +26,7 @@
26 26
27 27 #include "class.h"
28 28 #include "hash.h"
  29 +#include "uuid.h"
29 30 #include "application/application.h"
30 31 #include "storage/storage.h"
31 32
... ... @@ -50,6 +51,9 @@ applicationCtor(void * _this, va_list * params)
50 51 */
51 52 this->users = va_arg(*params, Storage);
52 53 this->passwords = va_arg(*params, Storage);
  54 + //this->roles = va_arg(*params, Storage);
  55 +
  56 + this->user_namespace = uuidParse(va_arg(*params, char *));
53 57
54 58 // initialize authenticators to use.
55 59 this->nauth = va_arg(*params, size_t);
... ... @@ -75,6 +79,8 @@ applicationDtor(void * _this)
75 79 Application this = _this;
76 80 size_t i;
77 81
  82 + delete(this->user_namespace);
  83 +
78 84 for (i=0; i<SESSION_LIVETIME; i++) {
79 85 delete(this->active_sessions[i]);
80 86 }
... ...
... ... @@ -28,6 +28,11 @@
28 28
29 29 #include "class.h"
30 30 #include "auth.h"
  31 +#include "uuid.h"
  32 +#include "storage/storage.h"
  33 +
  34 +#include "interface/serializable.h"
  35 +#include "interface/indexable.h"
31 36
32 37 #include "utils/memory.h"
33 38 #include "application/application.h"
... ... @@ -40,40 +45,63 @@ applicationLogin(
40 45 Session session)
41 46 {
42 47 size_t i;
  48 + Uuid search;
  49 + int authenticated = 0;
  50 +
  51 + User user = new(User, NULL);
  52 +
  53 + user->email = CRED_PWD(credential).user;
  54 + user->nemail = &CRED_PWD(credential).nuser;
  55 + search = indexUuid(user, this->user_namespace);
43 56
44 57 for (i=0; i<this->nauth; i++) {
45   - if (authenticate(this->auth[i], credential)) {
46   - session->user = new(User, NULL);
  58 + if (authenticate(this->auth[i], credential, search)) {
  59 + session->user = user;
47 60
48 61 switch (credential->type) {
49 62 case CRED_PASSWORD:
50   - session->user->email = CRED_PWD(credential).user;
51   - session->user->nemail = &CRED_PWD(credential).nuser;
52   -
53   - if (NULL == userLoad(session->user, this->users)) {
54   - // this is an ldap user that has not yet set
55   - // additional user informations.
56   - /** \todo again...change the keys to id's */
57   - session->user->email = NULL;
58   - delete(session->user);
59   - session->user = new(User,
60   - CRED_PWD(credential).user,
61   - CRED_PWD(credential).nuser,
62   - CSTRA(""),
63   - CSTRA(""));
64   - }
  63 + {
  64 + char * user_serialized;
  65 + size_t nuser_serialized;
  66 +
  67 + storageGet(
  68 + this->users,
  69 + (char *)(search->uuid).value,
  70 + sizeof((search->uuid).value),
  71 + &user_serialized,
  72 + &nuser_serialized);
65 73
  74 + if (NULL != user_serialized) {
  75 + unserialize(
  76 + session->user,
  77 + (unsigned char *)user_serialized,
  78 + nuser_serialized);
  79 + MEM_FREE(user_serialized);
  80 + } else {
  81 + // this is a user authenticated via another method
  82 + // than the password database and has not yet set
  83 + // additional user informations.
  84 + session->user = NULL;
  85 + delete(session->user);
  86 + session->user = new(User,
  87 + CRED_PWD(credential).user,
  88 + CRED_PWD(credential).nuser,
  89 + CSTRA(""),
  90 + CSTRA(""));
  91 + }
  92 + }
66 93 break;
67 94
68 95 default:
69 96 break;
70 97 }
71 98
72   - return 1;
  99 + authenticated = 1;
  100 + break;
73 101 }
74 102 }
75 103
76   - return 0;
  104 + return authenticated;
77 105 }
78 106
79 107 // vim: set ts=4 sw=4:
... ...
... ... @@ -43,7 +43,7 @@ applicationSessionCleanup(Application this, time_t now)
43 43 }
44 44
45 45 if (0 < expired && SESSION_LIVETIME > expired) {
46   - Hash * tmp_buf = memCalloc(SESSION_LIVETIME, sizeof(Hash));
  46 + Hash * tmp_buf = memCalloc(SESSION_LIVETIME, sizeof(Hash));
47 47
48 48 memcpy(
49 49 &(tmp_buf[expired]),
... ...
... ... @@ -29,8 +29,13 @@
29 29 #include "class.h"
30 30 #include "auth.h"
31 31 #include "user.h"
  32 +#include "uuid.h"
  33 +#include "storage/storage.h"
32 34 #include "application/application.h"
33 35
  36 +#include "interface/serializable.h"
  37 +#include "interface/indexable.h"
  38 +
34 39 #include "utils/memory.h"
35 40 #include "commons.h"
36 41
... ... @@ -44,17 +49,12 @@ applicationSignup(
44 49 unsigned char hash_data[SALT_SIZE+HASH_SIZE];
45 50 unsigned char * salt = NULL;
46 51 unsigned char * hash = hash_data+SALT_SIZE;
  52 + char * user_serialized;
  53 + size_t nuser_serialized;
  54 + Uuid index;
47 55
48   - if (NULL != userLoad(user, this->users)) {
49   - /*
50   - * if any user is found with this email return false
51   - * as on signup equal email adresses are not allowed
52   - * at all.
53   - */
54   - return 0;
55   - }
56   -
57   - userSave(user, this->users);
  56 + index = indexUuid(user, this->user_namespace);
  57 + serialize(user, (unsigned char **)&user_serialized, &nuser_serialized);
58 58
59 59 if (FALSE == hash_pw(
60 60 CRED_PWD(cred).pass,
... ... @@ -69,13 +69,23 @@ applicationSignup(
69 69 }
70 70
71 71 memcpy(hash_data, salt, SALT_SIZE);
72   -
73 72 MEM_FREE(salt);
74 73
  74 + /**
  75 + * \todo
  76 + * Add error handling here...
  77 + */
  78 + storagePut(
  79 + this->users,
  80 + (char *)(index->uuid).value,
  81 + sizeof((index->uuid).value),
  82 + user_serialized,
  83 + nuser_serialized);
  84 +
75 85 storagePut(
76 86 this->passwords,
77   - CRED_PWD(cred).user,
78   - CRED_PWD(cred).nuser,
  87 + (char *)(index->uuid).value,
  88 + sizeof((index->uuid).value),
79 89 (char *)hash_data,
80 90 SALT_SIZE + HASH_SIZE);
81 91
... ...
... ... @@ -20,6 +20,7 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
  23 +#include "uuid.h"
23 24 #include "auth/auth.h"
24 25 #include "auth/credential.h"
25 26 #include "auth/interface/auth.h"
... ... @@ -30,11 +31,11 @@ const struct interface i_Auth = {
30 31 };
31 32
32 33 int
33   -authenticate(void * auth, Credential cred)
  34 +authenticate(void * auth, Credential cred, Uuid user_index)
34 35 {
35 36 int ret;
36 37
37   - RETCALL(auth, Auth, authenticate, ret, cred);
  38 + RETCALL(auth, Auth, authenticate, ret, cred, user_index);
38 39
39 40 return ret;
40 41 }
... ...
... ... @@ -27,6 +27,7 @@
27 27 #include <ldap.h>
28 28
29 29 #include "class.h"
  30 +#include "uuid.h"
30 31 #include "utils/memory.h"
31 32 #include "commons.h"
32 33
... ... @@ -69,7 +70,7 @@ authLdapDtor(void * _this)
69 70
70 71 static
71 72 int
72   -authLdapAuthenticate(void * _this, Credential cred)
  73 +authLdapAuthenticate(void * _this, Credential cred, Uuid user_index)
73 74 {
74 75 AuthLdap this = _this;
75 76 char who[256];
... ...
... ... @@ -23,6 +23,8 @@
23 23 #include "class.h"
24 24 #include "storage/storage.h"
25 25 #include "auth.h"
  26 +#include "uuid.h"
  27 +#include "user.h"
26 28 #include "commons.h"
27 29 #include "utils/memory.h"
28 30
... ... @@ -45,7 +47,7 @@ authStorageDtor(void * _this)
45 47
46 48 static
47 49 int
48   -authStorageAuthenticate(void * _this, Credential cred)
  50 +authStorageAuthenticate(void * _this, Credential cred, Uuid user_index)
49 51 {
50 52 AuthStorage this = _this;
51 53
... ... @@ -59,8 +61,8 @@ authStorageAuthenticate(void * _this, Credential cred)
59 61
60 62 storageGet(
61 63 this->store,
62   - CRED_PWD(cred).user,
63   - CRED_PWD(cred).nuser,
  64 + (char *)(user_index->uuid).value,
  65 + sizeof((user_index->uuid).value),
64 66 (char **)&found_hash,
65 67 &nfound_hash);
66 68
... ...
... ... @@ -20,32 +20,23 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -#include <sys/types.h>
24   -#include <string.h>
25   -
26   -#include "user.h"
27   -#include "storage/storage.h"
28 23 #include "class.h"
  24 +#include "uuid.h"
  25 +#include "interface/indexable.h"
29 26
30   -#include "utils/memory.h"
31   -
  27 +const struct interface i_Indexable = {
  28 + "indexable",
  29 + 1
  30 +};
32 31
33   -void
34   -userSave(User this, Storage storage)
  32 +Uuid
  33 +indexUuid(void * indexable, Uuid namespace)
35 34 {
36   - size_t storage_size =
37   - *this->nemail + 1 +
38   - *this->nfirstname + 1 +
39   - *this->nsurname + 1 +
40   - 3 * sizeof(size_t);
  35 + Uuid ret;
  36 +
  37 + RETCALL(indexable, Indexable, uuid, ret, namespace);
41 38
42   - /**
43   - * \todo user return value for error handling
44   - */
45   - storageUpdate(
46   - storage,
47   - this->id, 36,
48   - this->email, storage_size);
  39 + return ret;
49 40 }
50 41
51 42 // vim: set ts=4 sw=4:
... ...
... ... @@ -20,48 +20,30 @@
20 20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 21 */
22 22
23   -#include <sys/types.h>
24   -#include <string.h>
25   -
26   -#include "user.h"
27   -#include "storage/storage.h"
28 23 #include "class.h"
29   -
30   -#include "utils/memory.h"
31   -
32   -
33   -User
34   -userLoad(User this, Storage storage)
  24 +#include "interface/serializable.h"
  25 +
  26 +const struct interface i_Serializable = {
  27 + "serializable",
  28 + 2
  29 +};
  30 +
  31 +void
  32 +serialize(
  33 + void * serializable,
  34 + unsigned char ** serialized,
  35 + size_t * nserialized)
35 36 {
36   - char * storage_data;
37   - size_t nstorage_data;
38   - size_t * user_data_sizes;
39   -
40   - if (NULL == storage) {
41   - return NULL;
42   - }
43   -
44   - storageGet(
45   - storage,
46   - this->email, *this->nemail,
47   - &storage_data, &nstorage_data);
48   -
49   - if (NULL == storage_data) {
50   - return NULL;
51   - }
52   -
53   - user_data_sizes =
54   - (size_t *)(storage_data + nstorage_data - 3 * sizeof(size_t));
55   -
56   - this->nemail = user_data_sizes;
57   - this->nfirstname = user_data_sizes + 1;
58   - this->nsurname = user_data_sizes + 2;
  37 + CALL(serializable, Serializable, serialize, serialized, nserialized);
  38 +}
59 39
60   - this->email = storage_data;
61   - this->firstname = this->email + *this->nemail + 1;
62   - this->surname = this->firstname + *this->nfirstname + 1;
63   -
64   - return this;
  40 +void
  41 +unserialize(
  42 + void * serializable,
  43 + const unsigned char * serialized,
  44 + size_t nserialized)
  45 +{
  46 + CALL(serializable, Serializable, unserialize, serialized, nserialized);
65 47 }
66 48
67 49 // vim: set ts=4 sw=4:
... ...
... ... @@ -207,6 +207,7 @@ main()
207 207 value,
208 208 users,
209 209 passwords,
  210 + "14de9e60-d497-4754-be72-f3bed52541fc",
210 211 2,
211 212 authLdap,
212 213 authStorage);
... ...
... ... @@ -5,5 +5,5 @@ AM_CFLAGS += -I../../include/
5 5
6 6 noinst_LTLIBRARIES = libuser.la
7 7
8   -libuser_la_SOURCES = user.c load.c save.c
  8 +libuser_la_SOURCES = user.c
9 9 libuser_la_CFLAGS = $(AM_CFLAGS)
... ...
... ... @@ -21,9 +21,12 @@
21 21 */
22 22
23 23 #include "user.h"
24   -#include "storage/storage.h"
  24 +#include "uuid.h"
25 25 #include "class.h"
26 26
  27 +#include "interface/serializable.h"
  28 +#include "interface/indexable.h"
  29 +
27 30 #include "utils/memory.h"
28 31
29 32
... ... @@ -31,9 +34,8 @@ static
31 34 int
32 35 userCtor(void * _this, va_list * params)
33 36 {
34   - User this = _this;
35   -
36   - char * email = va_arg(* params, char *);
  37 + User this = _this;
  38 + char * email = va_arg(* params, char *);
37 39
38 40 if (NULL != email) {
39 41 size_t nemail = va_arg(* params, size_t);
... ... @@ -84,7 +86,66 @@ userDtor(void * _this)
84 86 }
85 87 }
86 88
  89 +static
  90 +void
  91 +userSerialize(
  92 + void * _this,
  93 + unsigned char ** serialized,
  94 + size_t * nserialized)
  95 +{
  96 + User this = _this;
  97 +
  98 + *nserialized =
  99 + *this->nemail + 1 +
  100 + *this->nfirstname + 1 +
  101 + *this->nsurname + 1 +
  102 + 3 * sizeof(size_t);
  103 +
  104 + *serialized = memMalloc(*nserialized);
  105 +
  106 + memcpy(*serialized, this->email, *nserialized);
  107 +}
  108 +
  109 +static
  110 +void
  111 +userUnserialize(
  112 + void * _this,
  113 + const unsigned char * serialized,
  114 + size_t nserialized)
  115 +{
  116 + User this = _this;
  117 + size_t * user_data_sizes;
  118 +
  119 + this->email = memMalloc(nserialized);
  120 + memcpy(this->email, serialized, nserialized);
  121 +
  122 + user_data_sizes =
  123 + (size_t *)(this->email + nserialized - 3 * sizeof(size_t));
  124 +
  125 + this->nemail = user_data_sizes;
  126 + this->nfirstname = user_data_sizes + 1;
  127 + this->nsurname = user_data_sizes + 2;
  128 +
  129 + this->firstname = this->email + *this->nemail + 1;
  130 + this->surname = this->firstname + *this->nfirstname + 1;
  131 +}
  132 +
  133 +static
  134 +Uuid
  135 +userIndexUuid(void * _this, Uuid namespace)
  136 +{
  137 + User this = _this;
  138 +
  139 + return uuidVersion3(
  140 + (unsigned char *)this->email,
  141 + *this->nemail,
  142 + namespace);
  143 +}
  144 +
  145 +
87 146 INIT_IFACE(Class, userCtor, userDtor, NULL);
88   -CREATE_CLASS(User, NULL, IFACE(Class));
  147 +INIT_IFACE(Serializable, userSerialize, userUnserialize);
  148 +INIT_IFACE(Indexable, userIndexUuid);
  149 +CREATE_CLASS(User, NULL, IFACE(Class), IFACE(Serializable), IFACE(Indexable));
89 150
90 151 // vim: set ts=4 sw=4:
... ...
Please register or login to post a comment