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"
8 #define OILS_AUTH_CACHE_PRFX "oils_auth_"
10 #define MODULENAME "open-ils.auth"
12 int osrfAppInitialize();
13 int osrfAppChildInit();
14 int osrfMathRun( osrfMethodContext* );
17 int osrfAppInitialize() {
19 osrfAppRegisterMethod(
21 "open-ils.auth.authenticate.init",
23 "Start the authentication process and returns the intermediate authentication seed"
24 " PARAMS( username )", 1, 0 );
26 osrfAppRegisterMethod(
28 "open-ils.auth.authenticate.complete",
30 "Completes the authentication process and returns the auth token "
31 "PARAMS(username, md5sum( seed + password ) )", 2, 0 );
33 osrfAppRegisterMethod(
35 "open-ils.auth.session.retrieve",
36 "oilsAuthSessionRetrieve",
37 "Returns the user object (password blanked) for the given login session "
38 "PARAMS( authToken )", 1, 0 );
40 osrfAppRegisterMethod(
42 "open-ils.auth.session.delete",
43 "oilsAuthSessionDelete",
44 "Destroys the given login session "
45 "PARAMS( authToken )", 1, 0 );
50 int osrfAppChildInit() {
54 int oilsAuthInit( osrfMethodContext* ctx ) {
55 OSRF_METHOD_VERIFY_CONTEXT(ctx);
58 char* username = NULL;
63 if( (username = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0))) ) {
65 seed = va_list_to_string( "%d.%d.%s", time(NULL), getpid(), username );
66 key = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, username );
68 md5seed = md5sum(seed);
69 osrfCachePutString( key, md5seed, 30 );
71 osrfLogDebug( "oilsAuthInit(): has seed %s and key %s", md5seed, key );
73 resp = jsonNewObject(md5seed);
74 osrfAppRespondComplete( ctx, resp );
87 int oilsAuthComplete( osrfMethodContext* ctx ) {
88 OSRF_METHOD_VERIFY_CONTEXT(ctx);
90 char* uname = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0));
91 char* password = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 1));
92 char* storageMethod = "open-ils.storage.direct.actor.user.search.usrname.atomic";
93 osrfMessage* omsg = NULL;
95 if( uname && password ) {
97 jsonObject* response = jsonParseString("{\"ilsevent\":0}");
99 /* grab the user object from storage */
100 osrfLogDebug( "oilsAuth calling method %s with username %s", storageMethod, uname );
102 osrfAppSession* session = osrfAppSessionClientInit( "open-ils.storage" ); /**/
103 //jsonObject* params = jsonNewObject(uname); /**/
104 jsonObject* params = jsonParseString("[\"%s\"]", uname);
105 int reqid = osrfAppSessionMakeRequest( session, params, storageMethod, 1, NULL );
106 jsonObjectFree(params);
107 osrfLogInternal("oilsAuth waiting from response from storage...");
108 omsg = osrfAppSessionRequestRecv( session, reqid, 60 ); /**/
109 osrfLogInternal("oilsAuth storage request returned");
112 osrfAppSessionFree(session);
113 return osrfAppRequestRespondException( ctx->session, ctx->request,
114 "No response from storage server for method %s", storageMethod );
117 jsonObject* userObj = osrfMessageGetResult(omsg);
119 char* _j = jsonObjectToJSON(userObj);
120 osrfLogDebug( "Auth received user object from storage: %s", _j );
123 /* the method is atomic, grab the first user we receive */
124 if( userObj ) userObj = jsonObjectGetIndex(userObj, 0);
126 if(!userObj) { /* XXX needs to be a 'friendly' exception */
127 osrfMessageFree(omsg);
128 osrfAppSessionFree(session);
129 jsonObjectSetKey(response, OILS_ILS_EVENT,
130 jsonNewNumberObject(OILS_ILS_EVENT_AUTH_FAILED));
131 osrfAppRespondComplete( ctx, response );
132 jsonObjectFree(response);
136 return osrfAppRequestRespondException( ctx->session,
137 ctx->request, "User %s not found in the database", uname );
141 char* realPassword = oilsFMGetString( userObj, "passwd" ); /**/
142 char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/
145 osrfMessageFree(omsg);
146 osrfAppSessionFree(session);
147 return osrfAppRequestRespondException( ctx->session,
148 ctx->request, "No authentication seed found. "
149 "open-ils.auth.authenticate.init must be called first");
152 osrfLogDebug( "oilsAuth retrieved seed from cache: %s", seed );
153 char* maskedPw = md5sum( "%s%s", seed, realPassword );
154 if(!maskedPw) return -1;
155 osrfLogDebug( "oilsAuth generated masked password %s. "
156 "Testing against provided password %s", maskedPw, password );
159 if( !strcmp( maskedPw, password ) ) {
161 osrfLogActivity( "User %s successfully logged in", uname );
163 char* string = va_list_to_string( "%d.%d.%s", getpid(), time(NULL), uname ); /**/
164 char* authToken = md5sum(string); /**/
165 char* authKey = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
167 osrfLogInternal("oilsAuthComplete(): Setting fieldmapper string on the user object");
168 oilsFMSetString( userObj, "passwd", "" );
169 osrfCachePutObject( authKey, userObj, 28800 ); /* XXX config value */
170 osrfLogInternal("oilsAuthComplete(): Placed user object into cache");
171 // response = jsonNewObject( authToken );
172 jsonObjectSetKey( response, "authtoken", jsonNewObject(authToken) );
173 free(string); free(authToken); free(authKey);
177 jsonObjectSetKey(response, OILS_ILS_EVENT,
178 jsonNewNumberObject(OILS_ILS_EVENT_AUTH_FAILED));
179 osrfLogInfo( "Login failed for for %s", uname );
182 osrfLogInternal("oilsAuthComplete responding to client");
183 osrfAppRespondComplete( ctx, response );
184 jsonObjectFree(response);
185 osrfMessageFree(omsg);
186 osrfAppSessionFree(session);
189 return osrfAppRequestRespondException( ctx->session, ctx->request,
190 "username and password required for method: %s", ctx->method->name );
197 int oilsAuthSessionRetrieve( osrfMethodContext* ctx ) {
198 OSRF_METHOD_VERIFY_CONTEXT(ctx);
200 char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0));
201 jsonObject* userObj = NULL;
204 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
205 userObj = osrfCacheGetObject( key ); /**/
209 osrfAppRespondComplete( ctx, userObj );
210 jsonObjectFree(userObj);
214 int oilsAuthSessionDelete( osrfMethodContext* ctx ) {
215 OSRF_METHOD_VERIFY_CONTEXT(ctx);
217 char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
218 jsonObject* resp = NULL;
221 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
222 osrfCacheRemove(key);
223 resp = jsonNewObject(authToken); /**/
227 osrfAppRespondComplete( ctx, resp );
228 jsonObjectFree(resp);