1 #include "opensrf/osrf_app_session.h"
2 #include "opensrf/osrf_application.h"
3 #include "objson/object.h"
4 #include "opensrf/osrf_log.h"
5 #include "oils_utils.h"
7 #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 osrfLogInit(MODULENAME);
21 osrfAppRegisterMethod(
23 "open-ils.auth.authenticate.init",
25 "Start the authentication process and returns the intermediate authentication seed",
28 osrfAppRegisterMethod(
30 "open-ils.auth.authenticate.complete",
32 "Completes the authentication process and returns the auth token",
33 "[ username, md5sum( seed + password ) ]", 2 );
35 osrfAppRegisterMethod(
37 "open-ils.auth.session.retrieve",
38 "oilsAuthSessionRetrieve",
39 "Returns the user object (password blanked) for the given login session",
42 osrfAppRegisterMethod(
44 "open-ils.auth.session.delete",
45 "oilsAuthSessionDelete",
46 "Destroys the given login session",
52 int osrfAppChildInit() {
56 int oilsAuthInit( osrfMethodContext* ctx ) {
57 OSRF_METHOD_VERIFY_CONTEXT(ctx);
60 char* username = NULL;
65 if( (username = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0))) ) {
67 seed = va_list_to_string( "%d.%d.%s", time(NULL), getpid(), username );
68 key = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, username );
70 md5seed = md5sum(seed);
71 osrfCachePutString( key, md5seed, 30 );
73 osrfLog( OSRF_DEBUG, "oilsAuthInit(): has seed %s and key %s", md5seed, key );
75 resp = jsonNewObject(md5seed);
76 osrfAppRequestRespondComplete( ctx->session, ctx->request, resp );
89 int oilsAuthComplete( osrfMethodContext* ctx ) {
90 OSRF_METHOD_VERIFY_CONTEXT(ctx);
92 char* uname = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0));
93 char* password = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 1));
94 char* storageMethod = "open-ils.storage.direct.actor.user.search.usrname.atomic";
96 if( uname && password ) {
98 /* grab the user object from storage */
99 osrfLog( OSRF_DEBUG, "oilsAuth calling method %s with username %s", storageMethod, uname );
101 osrfAppSession* session = osrfAppSessionClientInit( "open-ils.storage" ); /**/
102 jsonObject* params = jsonNewObject(uname); /**/
103 int reqid = osrfAppSessionMakeRequest( session, params, storageMethod, 1, NULL );
104 jsonObjectFree(params);
105 osrfMessage* omsg = osrfAppSessionRequestRecv( session, reqid, 60 ); /**/
108 osrfAppSessionFree(session);
109 return osrfAppRequestRespondException( ctx->session, ctx->request,
110 "No response from storage server for method %s", storageMethod );
113 jsonObject* userObj = osrfMessageGetResult(omsg);
115 char* _j = jsonObjectToJSON(userObj);
116 osrfLog( OSRF_DEBUG, "Auth received user object from storage: %s", _j );
119 /* the method is atomic, grab the first user we receive */
120 if( userObj ) userObj = jsonObjectGetIndex(userObj, 0);
122 if(!userObj) { /* XXX needs to be a 'friendly' exception */
123 osrfMessageFree(omsg);
124 osrfAppSessionFree(session);
125 return osrfAppRequestRespondException( ctx->session,
126 ctx->request, "User %s not found in the database", uname );
129 char* realPassword = oilsFMGetString( userObj, "passwd" ); /**/
130 char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/
133 osrfMessageFree(omsg);
134 osrfAppSessionFree(session);
135 return osrfAppRequestRespondException( ctx->session,
136 ctx->request, "No authentication seed found. "
137 "open-ils.auth.authenticate.init must be called first");
140 osrfLog( OSRF_DEBUG, "oilsAuth retrieved seed from cache: %s", seed );
141 char* maskedPw = md5sum( "%s%s", seed, realPassword );
142 if(!maskedPw) return -1;
143 osrfLog( OSRF_DEBUG, "oilsAuth generated masked password %s. "
144 "Testing against provided password %s", maskedPw, password );
146 jsonObject* response;
148 if( !strcmp( maskedPw, password ) ) {
150 osrfLog( OSRF_INFO, "Login successful for %s", uname );
151 char* string = va_list_to_string( "%d.%d.%s", getpid(), time(NULL), uname ); /**/
152 char* authToken = md5sum(string); /**/
153 char* authKey = va_list_to_string( "%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
154 oilsFMSetString( userObj, "passwd", "" );
155 osrfCachePutObject( authKey, userObj, 28800 ); /* XXX config value */
156 response = jsonNewObject( authToken );
157 free(string); free(authToken); free(authKey);
160 osrfLog( OSRF_INFO, "Login failed for for %s", uname );
161 response = jsonNewNumberObject(0);
164 osrfAppRequestRespondComplete( ctx->session, ctx->request, response );
165 jsonObjectFree(response);
166 osrfMessageFree(omsg);
167 osrfAppSessionFree(session);
170 return osrfAppRequestRespondException( ctx->session, ctx->request,
171 "username and password required for method: %s", ctx->method->name );
178 int oilsAuthSessionRetrieve( osrfMethodContext* ctx ) {
179 OSRF_METHOD_VERIFY_CONTEXT(ctx);
181 char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0));
182 jsonObject* userObj = NULL;
185 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
186 userObj = osrfCacheGetObject( key ); /**/
190 osrfAppRequestRespondComplete( ctx->session, ctx->request, userObj );
191 jsonObjectFree(userObj);
195 int oilsAuthSessionDelete( osrfMethodContext* ctx ) {
196 OSRF_METHOD_VERIFY_CONTEXT(ctx);
198 char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
199 jsonObject* resp = NULL;
202 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
203 osrfCacheRemove(key);
204 resp = jsonNewObject(authToken); /**/
208 osrfAppRequestRespondComplete( ctx->session, ctx->request, resp );
209 jsonObjectFree(resp);