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"
9 #define OILS_AUTH_CACHE_PRFX "oils_auth_"
11 #define MODULENAME "open-ils.auth"
13 int osrfAppInitialize();
14 int osrfAppChildInit();
15 int osrfMathRun( osrfMethodContext* );
18 int osrfAppInitialize() {
20 osrfAppRegisterMethod(
22 "open-ils.auth.authenticate.init",
24 "Start the authentication process and returns the intermediate authentication seed"
25 " PARAMS( username )", 1, 0 );
27 osrfAppRegisterMethod(
29 "open-ils.auth.authenticate.complete",
31 "Completes the authentication process and returns the auth token "
32 "PARAMS(username, md5sum( seed + password ), type )", 2, 0 );
34 osrfAppRegisterMethod(
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 );
41 osrfAppRegisterMethod(
43 "open-ils.auth.session.delete",
44 "oilsAuthSessionDelete",
45 "Destroys the given login session "
46 "PARAMS( authToken )", 1, 0 );
51 int osrfAppChildInit() {
55 int oilsAuthInit( osrfMethodContext* ctx ) {
56 OSRF_METHOD_VERIFY_CONTEXT(ctx);
59 char* username = NULL;
64 if( (username = jsonObjectGetString(jsonObjectGetIndex(ctx->params, 0))) ) {
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 );
69 md5seed = md5sum(seed);
70 osrfCachePutString( key, md5seed, 30 );
72 osrfLogDebug( "oilsAuthInit(): has seed %s and key %s", md5seed, key );
74 resp = jsonNewObject(md5seed);
75 osrfAppRespondComplete( ctx, resp );
88 int oilsAuthComplete( osrfMethodContext* ctx ) {
89 OSRF_METHOD_VERIFY_CONTEXT(ctx);
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";
96 if( uname && password ) {
98 oilsEvent* response = NULL;
99 jsonObject* userObj = oilsUtilsFetchUserByUsername( uname ); /* XXX */
102 response = oilsNewEvent( OILS_EVENT_AUTH_FAILED );
103 osrfAppRespondComplete( ctx, oilsEventToJSON(response) );
104 oilsEventFree(response);
108 /* check to see if the user is allowed to login */
109 oilsEvent* perm = NULL;
111 if(!strcmp(type, "opac")) {
112 char* permissions[] = { "OPAC_LOGIN" };
113 perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 );
115 } else if(!strcmp(type, "staff")) {
116 char* permissions[] = { "STAFF_LOGIN" };
117 perm = oilsUtilsCheckPerms( oilsFMGetObjectId( userObj ), -1, permissions, 1 );
121 jsonObjectFree(userObj);
122 osrfAppRespondComplete( ctx, oilsEventToJSON(perm) );
129 char* realPassword = oilsFMGetString( userObj, "passwd" ); /**/
130 char* seed = osrfCacheGetString( "%s%s", OILS_AUTH_CACHE_PRFX, uname ); /**/
133 return osrfAppRequestRespondException( ctx->session,
134 ctx->request, "No authentication seed found. "
135 "open-ils.auth.authenticate.init must be called first");
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 );
145 if( !strcmp( maskedPw, password ) ) {
147 osrfLogActivity( "User %s successfully logged in", uname );
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 ); /**/
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);
163 response = oilsNewEvent( OILS_EVENT_AUTH_FAILED );
164 osrfLogInfo( "Login failed for for %s", uname );
167 osrfLogInternal("oilsAuthComplete responding to client");
168 osrfAppRespondComplete( ctx, oilsEventToJSON(response) );
169 oilsEventFree(response);
172 return osrfAppRequestRespondException( ctx->session, ctx->request,
173 "username and password required for method: %s", ctx->method->name );
180 int oilsAuthSessionRetrieve( osrfMethodContext* ctx ) {
181 OSRF_METHOD_VERIFY_CONTEXT(ctx);
183 char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0));
184 jsonObject* userObj = NULL;
187 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
188 userObj = osrfCacheGetObject( key ); /**/
192 osrfAppRespondComplete( ctx, userObj );
193 jsonObjectFree(userObj);
197 int oilsAuthSessionDelete( osrfMethodContext* ctx ) {
198 OSRF_METHOD_VERIFY_CONTEXT(ctx);
200 char* authToken = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
201 jsonObject* resp = NULL;
204 char* key = va_list_to_string("%s%s", OILS_AUTH_CACHE_PRFX, authToken ); /**/
205 osrfCacheRemove(key);
206 resp = jsonNewObject(authToken); /**/
210 osrfAppRespondComplete( ctx, resp );
211 jsonObjectFree(resp);