]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/oils_auth.c
added some utility functions like permissions checking, one-off requests, etc.
[Evergreen.git] / Open-ILS / src / c-apps / oils_auth.c
1 #include "opensrf/osrf_app_session.h"
2 #include "opensrf/osrf_application.h"
3 #include "objson/object.h"
4 #include "opensrf/log.h"
5 #include "oils_utils.h"
6 #include "oils_constants.h"
7 #include "oils_event.h"
8
9 #define OILS_AUTH_CACHE_PRFX "oils_auth_"
10
11 #define MODULENAME "open-ils.auth"
12
13 int osrfAppInitialize();
14 int osrfAppChildInit();
15 int osrfMathRun( osrfMethodContext* );
16
17
18 int osrfAppInitialize() {
19
20         osrfAppRegisterMethod( 
21                 MODULENAME, 
22                 "open-ils.auth.authenticate.init", 
23                 "oilsAuthInit", 
24                 "Start the authentication process and returns the intermediate authentication seed"
25                 " PARAMS( username )", 1, 0 );
26
27         osrfAppRegisterMethod( 
28                 MODULENAME, 
29                 "open-ils.auth.authenticate.complete", 
30                 "oilsAuthComplete", 
31                 "Completes the authentication process and returns the auth token "
32                 "PARAMS(username, md5sum( seed + password ), type )", 2, 0 );
33
34         osrfAppRegisterMethod( 
35                 MODULENAME, 
36                 "open-ils.auth.session.retrieve", 
37                 "oilsAuthSessionRetrieve", 
38                 "Returns the user object (password blanked) for the given login session "
39                 "PARAMS( authToken )", 1, 0 );
40
41         osrfAppRegisterMethod( 
42                 MODULENAME, 
43                 "open-ils.auth.session.delete", 
44                 "oilsAuthSessionDelete", 
45                 "Destroys the given login session "
46                 "PARAMS( authToken )",  1, 0 );
47
48         return 0;
49 }
50
51 int osrfAppChildInit() {
52         return 0;
53 }
54
55 int oilsAuthInit( osrfMethodContext* ctx ) {
56         OSRF_METHOD_VERIFY_CONTEXT(ctx); 
57
58         jsonObject* resp;
59         char* username = NULL;
60         char* seed = NULL;
61         char* md5seed = NULL;
62         char* key = NULL;
63
64         if( (username = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0))) ) {
65
66                 seed = va_list_to_string( "%d.%d.%s", time(NULL), getpid(), username );
67                 key = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, username );
68
69                 md5seed = md5sum(seed);
70                 osrfCachePutString( key, md5seed, 30 );
71
72                 osrfLogDebug( "oilsAuthInit(): has seed %s and key %s", md5seed, key );
73
74                 resp = jsonNewObject(md5seed);  
75                 osrfAppRespondComplete( ctx, resp );
76
77                 jsonObjectFree(resp);
78                 free(seed);
79                 free(md5seed);
80                 free(key);
81                 return 0;
82         }
83
84         return -1;
85 }
86
87
88 int oilsAuthComplete( osrfMethodContext* ctx ) {
89         OSRF_METHOD_VERIFY_CONTEXT(ctx); 
90
91         char* uname = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0));
92         char* password = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 1));
93         char* type              = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 2));
94         if(!type) type = "staff";
95
96         if( uname && password ) {
97
98                 oilsEvent* response = NULL;
99                 jsonObject* userObj = oilsUtilsFetchUserByUsername( uname ); /* XXX */
100                 
101                 if(!userObj) { 
102                         response = oilsNewEvent( OILS_EVENT_AUTH_FAILED );
103                         osrfAppRespondComplete( ctx, oilsEventToJSON(response) ); 
104                         oilsEventFree(response);
105                         return 0;
106                 }
107
108                 /* check to see if the user is allowed to login */
109                 oilsEvent* perm = NULL;
110
111                 if(!strcmp(type, "opac")) {
112                         char* permissions[] = { "OPAC_LOGIN" };
113                         perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 );
114
115                 } else if(!strcmp(type, "staff")) {
116                         char* permissions[] = { "STAFF_LOGIN" };
117                         perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 );
118                 }
119
120                 if(perm) {
121                         jsonObjectFree(userObj);
122                         osrfAppRespondComplete( ctx, oilsEventToJSON(perm) ); 
123                         oilsEventFree(perm);
124                         return 0;
125                 }
126
127
128
129                 char* realPassword = oilsFMGetString( userObj, "passwd" ); /**/
130                 char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/
131
132                 if(!seed) {
133                         return osrfAppRequestRespondException( ctx->session,
134                                 ctx->request, "No authentication seed found. "
135                                 "open-ils.auth.authenticate.init must be called first");
136                 }
137
138                 osrfLogDebug( "oilsAuth retrieved seed from cache: %s", seed );
139                 char* maskedPw = md5sum( "%s%s", seed, realPassword );
140                 if(!maskedPw) return -1;
141                 osrfLogDebug( "oilsAuth generated masked password %s. "
142                                 "Testing against provided password %s", maskedPw, password );
143
144
145                 if( !strcmp( maskedPw, password ) ) {
146
147                         osrfLogActivity( "User %s successfully logged in", uname );
148
149                         char* string = va_list_to_string( "%d.%d.%s", getpid(), time(NULL), uname ); /**/
150                         char* authToken = md5sum(string); /**/
151                         char* authKey = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
152
153                         osrfLogInternal("oilsAuthComplete(): Setting fieldmapper string on the user object");
154                         oilsFMSetString( userObj, "passwd", "" );
155                         osrfCachePutObject( authKey, userObj, 28800 ); /* XXX config value */
156                         osrfLogInternal("oilsAuthComplete(): Placed user object into cache");
157                         response = oilsNewEvent2( OILS_EVENT_SUCCESS, jsonNewObject(authToken) );
158                         free(string); free(authToken); free(authKey);
159                         jsonObjectFree(userObj);
160
161                 } else {
162
163                         response = oilsNewEvent( OILS_EVENT_AUTH_FAILED );
164                         osrfLogInfo( "Login failed for for %s", uname );
165                 }
166
167                 osrfLogInternal("oilsAuthComplete responding to client");
168                 osrfAppRespondComplete( ctx, oilsEventToJSON(response) ); 
169                 oilsEventFree(response);
170
171         } else {
172                 return osrfAppRequestRespondException( ctx->session, ctx->request, 
173                         "username and password required for method: %s", ctx->method->name );
174         }
175
176         return 0;
177
178 }
179
180 int oilsAuthSessionRetrieve( osrfMethodContext* ctx ) {
181         OSRF_METHOD_VERIFY_CONTEXT(ctx); 
182
183         char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0));
184         jsonObject* userObj = NULL;
185
186         if( authToken ){
187                 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
188                 userObj = osrfCacheGetObject( key ); /**/
189                 free(key);
190         }
191
192         osrfAppRespondComplete( ctx, userObj );
193         jsonObjectFree(userObj);
194         return 0;
195 }
196
197 int oilsAuthSessionDelete( osrfMethodContext* ctx ) {
198         OSRF_METHOD_VERIFY_CONTEXT(ctx); 
199
200         char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
201         jsonObject* resp = NULL;
202
203         if( authToken ) {
204                 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
205                 osrfCacheRemove(key);
206                 resp = jsonNewObject(authToken); /**/
207                 free(key);
208         }
209
210         osrfAppRespondComplete( ctx, resp );
211         jsonObjectFree(resp);
212         return 0;
213 }
214
215
216