char claimed_id[1024];
char server[1024];
int verified;
+ HashList *sreg_keys;
};
long fetched_usernum;
char *data;
int data_len;
+ char buf[2048];
if (!who) return(1);
if (!claimed_id) return(1);
cdb_store(CDB_OPENID, claimed_id, strlen(claimed_id), data, data_len);
free(data);
- CtdlLogPrintf(CTDL_INFO, "%s has been attached to %s (%ld)\n",
- claimed_id, who->fullname, who->usernum);
+ snprintf(buf, sizeof buf, "User <%s> (#%ld) has claimed the OpenID URL %s\n",
+ who->fullname, who->usernum, claimed_id);
+ aide_message(buf, "OpenID claim");
+ CtdlLogPrintf(CTDL_INFO, "%s", buf);
return(0);
}
/* Go through the hash list, deleting keys we stored in it */
- HashPos = GetNewHashPos();
+ HashPos = GetNewHashPos(keys, 0);
while (GetNextHashPos(keys, HashPos, &len, &Key, &Value)!=0)
{
CtdlLogPrintf(CTDL_DEBUG, "Deleting associated OpenID <%s>\n", Value);
}
+/*
+ * Attempt to register (populate the vCard) the currently-logged-in user
+ * using the data from Simple Registration Extension, if present.
+ */
+void populate_vcard_from_sreg(HashList *sreg_keys) {
+
+ struct vCard *v;
+ int pop = 0; /* number of fields populated */
+ char *data = NULL;
+ char *postcode = NULL;
+ char *country = NULL;
+
+ if (!sreg_keys) return;
+ v = vcard_new();
+ if (!v) return;
+
+ if (GetHash(sreg_keys, "identity", 8, (void *) &data)) {
+ vcard_add_prop(v, "url;type=openid", data);
+ ++pop;
+ }
+
+ if (GetHash(sreg_keys, "sreg.email", 10, (void *) &data)) {
+ vcard_add_prop(v, "email;internet", data);
+ ++pop;
+ }
+
+ if (GetHash(sreg_keys, "sreg.nickname", 13, (void *) &data)) {
+ vcard_add_prop(v, "nickname", data);
+ ++pop;
+ }
+
+ if (GetHash(sreg_keys, "sreg.fullname", 13, (void *) &data)) {
+ char n[256];
+ vcard_add_prop(v, "fn", data);
+ vcard_fn_to_n(n, data, sizeof n);
+ vcard_add_prop(v, "n", n);
+ ++pop;
+ }
+
+ if (!GetHash(sreg_keys, "sreg.postcode", 13, (void *) &postcode)) {
+ postcode = NULL;
+ }
+
+ if (!GetHash(sreg_keys, "sreg.country", 12, (void *) &country)) {
+ country = NULL;
+ }
+
+ if (postcode || country) {
+ char adr[256];
+ snprintf(adr, sizeof adr, ";;;;;%s;%s",
+ (postcode ? postcode : ""),
+ (country ? country : "")
+ );
+ vcard_add_prop(v, "adr", adr);
+ ++pop;
+ }
+
+ if (GetHash(sreg_keys, "sreg.dob", 8, (void *) &data)) {
+ vcard_add_prop(v, "bday", data);
+ ++pop;
+ }
+
+ if (GetHash(sreg_keys, "sreg.gender", 11, (void *) &data)) {
+ vcard_add_prop(v, "x-funambol-gender", data);
+ ++pop;
+ }
+
+ /* Only save the vCard if there is some useful data in it */
+ if (pop > 0) {
+ char *ser;
+ ser = vcard_serialize(v);
+ if (ser) {
+ CtdlWriteObject(USERCONFIGROOM, "text/x-vcard",
+ ser, strlen(ser)+1, &CC->user, 0, 0, 0
+ );
+ free(ser);
+ }
+ }
+ vcard_free(v);
+}
+
+
+/*
+ * Create a new user account, manually specifying the name, after successfully
+ * verifying an OpenID (which will of course be attached to the account)
+ */
+void cmd_oidc(char *argbuf) {
+ struct ctdl_openid *oiddata = (struct ctdl_openid *) CC->openid_data;
+
+ if (!oiddata->verified) {
+ cprintf("%d You have not verified an OpenID yet.\n", ERROR);
+ return;
+ }
+
+ /* We can make the semantics of OIDC exactly the same as NEWU, simply
+ * by _calling_ cmd_newu() and letting it run. Very clever!
+ */
+ cmd_newu(argbuf);
+
+ /* Now, if this logged us in, we have to attach the OpenID */
+ if (CC->logged_in) {
+ attach_openid(&CC->user, oiddata->claimed_id);
+ if (oiddata->sreg_keys != NULL) {
+ populate_vcard_from_sreg(oiddata->sreg_keys);
+ }
+ }
+
+}
+
+
+
/*
* Detach an OpenID from the currently logged in account
/*
* Attempt to auto-create a new Citadel account using the nickname from Simple Registration Extension
*/
-int openid_create_user_via_sri(char *claimed_id, HashList *sri_keys)
+int openid_create_user_via_sreg(char *claimed_id, HashList *sreg_keys)
{
char *desired_name = NULL;
char new_password[32];
if (config.c_auth_mode != AUTHMODE_NATIVE) return(1);
if (config.c_disable_newu) return(2);
if (CC->logged_in) return(3);
- if (!GetHash(sri_keys, "sreg.nickname", 13, (void *) &desired_name)) return(4);
+ if (!GetHash(sreg_keys, "sreg.nickname", 13, (void *) &desired_name)) return(4);
CtdlLogPrintf(CTDL_DEBUG, "The desired account name is <%s>\n", desired_name);
snprintf(new_password, sizeof new_password, "%08lx%08lx", random(), random());
CtdlSetPassword(new_password);
attach_openid(&CC->user, claimed_id);
+ populate_vcard_from_sreg(sreg_keys);
return(0);
}
-// FIXME we still have to set up the vCard
-
-// identity = [50] http://uncensored.citadel.org/~ajc/MyID.config.php
-// sreg.nickname = [17] IGnatius T Foobar
-// sreg.email = [26] ajc@uncensored.citadel.org
-// sreg.fullname = [10] Art Cancro
-// sreg.postcode = [5] 10549
-// sreg.country = [2] US
-
-
/*
* If a user account exists which is associated with the Claimed ID, log it in and return zero.
struct CitContext *CCC = CC; /* CachedCitContext - performance boost */
struct ctdl_openid *oiddata;
- /* commented out because we may be attempting to attach an OpenID to
- * an existing account that is logged in
- *
- if (CCC->logged_in) {
- cprintf("%d Already logged in.\n", ERROR + ALREADY_LOGGED_IN);
- return;
- }
- */
+ oiddata = (struct ctdl_openid *) CCC->openid_data;
- if (CCC->openid_data != NULL) {
+ if (oiddata != NULL) {
+ if (oiddata->sreg_keys != NULL) {
+ DeleteHash(&oiddata->sreg_keys);
+ oiddata->sreg_keys = NULL;
+ }
free(CCC->openid_data);
}
oiddata = malloc(sizeof(struct ctdl_openid));
urlesc(escaped_return_to, sizeof escaped_return_to, return_to);
urlesc(escaped_trust_root, sizeof escaped_trust_root, trust_root);
urlesc(escaped_sreg_optional, sizeof escaped_sreg_optional,
- "nickname,email,fullname,postcode,country");
+ "nickname,email,fullname,postcode,country,dob,gender");
snprintf(redirect_string, sizeof redirect_string,
"%s"
logged_in_response();
}
+ /*
+ * If this system does not allow self-service new user registration, the
+ * remaining modes do not apply, so fail here and now.
+ */
+ else if (config.c_disable_newu) {
+ cprintf("fail\n");
+ }
+
/*
* New user whose OpenID is verified and Simple Registration Extension is in use?
*/
- else if (openid_create_user_via_sri(oiddata->claimed_id, keys) == 0) {
+ else if (openid_create_user_via_sreg(oiddata->claimed_id, keys) == 0) {
cprintf("authenticate\n%s\n%s\n", CC->user.fullname, CC->user.password);
logged_in_response();
}
}
cprintf("000\n");
- /*
- * We will eventually do something with the data in the hash list.
- *
- long len;
- void *Value;
- char *Key;
- HashPos *HashPos;
- HashPos = GetNewHashPos();
- while (GetNextHashPos(keys, HashPos, &len, &Key, &Value)!=0)
- {
+ if (oiddata->sreg_keys != NULL) {
+ DeleteHash(&oiddata->sreg_keys);
+ oiddata->sreg_keys = NULL;
}
- DeleteHashPos(&HashPos);
- */
-
- DeleteHash(&keys); /* This will free() all the key data for us */
+ oiddata->sreg_keys = keys;
}
* This cleanup function blows away the temporary memory used by this module.
*/
void openid_cleanup_function(void) {
+ struct ctdl_openid *oiddata = (struct ctdl_openid *) CC->openid_data;
- if (CC->openid_data != NULL) {
+ if (oiddata != NULL) {
CtdlLogPrintf(CTDL_DEBUG, "Clearing OpenID session state\n");
- free(CC->openid_data);
+ if (oiddata->sreg_keys != NULL) {
+ DeleteHash(&oiddata->sreg_keys);
+ oiddata->sreg_keys = NULL;
+ }
+ free(oiddata);
}
}
CTDL_MODULE_INIT(openid_rp)
{
- if (!threading)
- {
+ if (!threading) {
curl_global_init(CURL_GLOBAL_ALL);
- CtdlRegisterProtoHook(cmd_oids, "OIDS", "Setup OpenID authentication");
- CtdlRegisterProtoHook(cmd_oidf, "OIDF", "Finalize OpenID authentication");
- CtdlRegisterProtoHook(cmd_oidl, "OIDL", "List OpenIDs associated with an account");
- CtdlRegisterProtoHook(cmd_oidd, "OIDD", "Detach an OpenID from an account");
+
+ /* Only enable the OpenID command set when native mode authentication is in use. */
+ if (config.c_auth_mode == AUTHMODE_NATIVE) {
+ CtdlRegisterProtoHook(cmd_oids, "OIDS", "Setup OpenID authentication");
+ CtdlRegisterProtoHook(cmd_oidf, "OIDF", "Finalize OpenID authentication");
+ CtdlRegisterProtoHook(cmd_oidl, "OIDL", "List OpenIDs associated with an account");
+ CtdlRegisterProtoHook(cmd_oidd, "OIDD", "Detach an OpenID from an account");
+ CtdlRegisterProtoHook(cmd_oidc, "OIDC", "Create new user after validating OpenID");
+ }
CtdlRegisterSessionHook(openid_cleanup_function, EVT_LOGOUT);
CtdlRegisterUserHook(openid_purge, EVT_PURGEUSER);
}
/* return our Subversion id for the Log */
return "$Id$";
}
-
-
-/* FIXME ... we have to add the new openid database to serv_vandelay.c */
-