Commit 080add7222b50d7d45594000abcd9ef0d97166ba
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
Showing
17 changed files
with
292 additions
and
108 deletions
... | ... | @@ -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 | ... | ... |
include/interface/indexable.h
0 → 100644
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: | ... | ... |
include/interface/serializable.h
0 → 100644
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: | ... | ... |
... | ... | @@ -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