Monday, November 08, 2010 at 12:04 AM.

system.verbs.builtins.mainResponder.members.checkMembership

on checkMembership (adrobject, adrparamtable) { //scriptError if no cookie and one is required
	<<Changes:
		<<7/30/99; 1:48:16 PM by PBS
			<<When redirecting someone who doesn't have the cookie (and membership is required) to the login page, add as search args the URL of the page the person is on. That way the login page can redirect the person back once they've logged in.
			<<In other words, instead of redirecting here: http://news.userland.com/member/login
			<<Redirect here: http://news.userland.com/member/login?http://news.userland.com/prefs/
		<<12/6/99; 4:08:33 PM by PBS
			<<This script was redundantly parsing the POST args into a table, even though they'd already been parsed. This was inefficient. Furthermore, it wasn't parsing multi-part file uploads properly, leading to the picture uploading bug reported by Manila users.
		<<04/10/00; 12:21:59 PM by PBS
			<<Support for hashed cookies, an optional new format which does not send the password in plain text.
		<<04/14/00; 8:22:52 PM by JES
			<<localized
		<<05/01/00; 7:05:43 PM by JES
			<<Changed getString calls to use a replacement table address instead of a lists
		<<08/31/00; 4:58:50 PM by PBS
			<<Updated to pass the address of the param table in calls to mainResponder.getString, since the call to html.getPageTableAddress may fail in mainResponder.getString. Matt Neuburg's diagnosis: http://frontier.userland.com/discuss/msgReader$5436
		<<10/27/00; 1:06:47 AM by PBS
			<<When passing the redirect parameter to the logon page, include the pathArgs, if any. This way if someone was trying to get to a msgReader$ page, they'll get there after they login.
		<<10/27/00; 10:38:34 PM by PBS
			<<Pass pta parameter to mainResponder.members.sendMail.
		<<12/29/00; 10:26:33 AM by PBS
			<<There was an error with blocked members -- the path to the localized string was incorrect, so the string wouldn't be found. Now it's correct.
		<<9/26/01; 4:17:25 PM by PBS
			<<Common situation -- membership not required and the user has no cookies. Short-circuit and return early.
		<<1/28/02; 10:18:24 PM by PBS
			<<It should not be a fatal error if for some reason the person's password is missing from their membership record.
	
	local (adratts = @adrparamtable^.responderAttributes, lookInGroup, flMustBeMember = false);
	if not defined (adratts^.members) { //the page does not require membership
		if not defined (adratts^.defaultMembershipGroup) { //if it's defined we look for the cookie
			return (true)};
		lookInGroup = adratts^.defaultMembershipGroup}
	else {
		lookInGroup = adratts^.members;
		flMustBeMember = true};
	if (not defined (adrparamtable^.requestHeaders.cookies)) and (not flMustBeMember) { //PBS 09/26/01: return early for this common situation
		return};
	local (adrmembers = mainResponder.members.getMembershipTable (lookInGroup));
	local (myCookieName = adrmembers^.cookieName);
	on cookieRedirector () {
		on hasGoodCookie () { //also sets up adrparamtable^.adrMemberInfo, if the cookie is cool
			with adrMembers^ { //find and parse the cookie
				if not defined (adrparamtable^.requestHeaders.cookies) {
					return (false)};
				local (innerCaseCookieName = string.innerCaseName (myCookieName));
				if defined (adrparamtable^.requestHeaders.cookies.[innerCaseCookieName]) { //we prefer the innerCased name
					<<Some versions of Netscape care about blanks in the cookie names, we're transitioning from using spaces
						<<the innerCasing should happen when we send back the cookie
						<<we should always prefer the innerCased version
					myCookieName = innerCaseCookieName}
				else {
					if not defined (adrparamtable^.requestHeaders.cookies.[myCookieName]) {
						return (false)}};
				
				local (cookieString = adrparamtable^.requestHeaders.cookies.[myCookieName]);
				local (mailAddress, adrMember);
				
				on getMemberAddress () {
					adrMember = @users.[mailaddress];
					bundle { //set adrMember thru callback, if it's defined
						try {
							local (adrcallback = @adrMembers^.callbacks.getMemberTableAddress);
							if defined (adrcallback^) {
								adrMember = adrcallback^ (mailaddress)}}};
					if not defined (adrMember^) {
						return (false)};
					if defined (adrMember^.blocked) {
						if adrMember^.blocked {
							local (replacementTable); new (tableType, @replacementTable); // 05/01/00 JES: use replacement table instead of a list
							replacementTable.mailaddress = mailaddress;
							scriptError (mainResponder.getString ("members.checkMembershipAccountBlocked", @replacementTable, pta:adrParamTable))}}; //PBS 08/31/00: pass pta // 4/14/00 JES: localized
					return (true)};
				on setMemberInfo () {
					adrparamtable^.adrMemberInfo = adrMember;
					adrparamtable^.memberGroupName = lookInGroup;
					local (adrhitcounter = @adrMember^.hitcount);
					if not defined (adrhitcounter^) {
						adrhitcounter^ = 1}
					else {
						adrhitcounter^++};
					adrMember^.lastVisit = clock.now ();
					return (true)}; //the cookie is good!
				
				if mainResponder.members.isHashedCookieFormat (cookieString) {
					local (cookieArgTable = mainResponder.members.cookieStringToTable (cookieString));
					mailAddress = cookieArgTable.id;
					if not (getMemberAddress ()) {
						return (false)};
					
					<<Authenticate and set adrMemberInfo if authentic.
					if not defined (adrMember^.password) { //PBS 01/28/02: should not be a fatal error
						return (false)};
					if mainResponder.members.compareHashes (cookieArgTable.h, adrMember^.password, lookInGroup) {
						setMemberInfo ();
						return (true)}}
				else {
					local (s = string.urlDecode (cookieString));
					mailaddress = string.nthField (s, "\t", 1);
					if not (getMemberAddress ()) {
						return (false)};
					local (password = string.nthField (s, "\t", 2));
					if not defined (adrMember^.password) {
						return (false)};
					if string.upper (adrMember^.password) == string.upper (password) {
						setMemberInfo (); //set adrMemberInfo
						
						bundle { //possibly upgrade the cookie to the new format
							if mainResponder.members.useHashedCookies (adrparamtable) {
								mainResponder.members.setCookie (mailAddress, adrMember^.password, adrMembers, adrparamtable, lookInGroup)}};
						
						return (true)}}; //the cookie is good
				
				return (false)}}; //not a good cookie
		if not hasGoodCookie () {
			if flMustBeMember {
				<<PBS 7/30/99: add as search args the page that you were on before the redirect happened. That way the login page can send you back where you came from after you've logged in.
				if defined (adrParamTable^.host) and defined (adrParamTable^.URI) {
					local (currentPage = adrParamTable^.uri);
					if adrParamTable^.pathArgs != "" {
						currentPage = currentPage + "$" + adrParamTable^.pathArgs};
					scriptError ("!redirect " + adratts^.urls^.memberLogon + "?http://" + adrParamTable^.host + currentPage)}
				else {
					scriptError ("!redirect " + adratts^.urls^.memberLogon)}}}};
	on userRequestsCookie () {
		local (adruser = mainResponder.members.getMemberTable (lookInGroup, string.urldecode (args.mailaddress)));
		local (replacementTable); new (tableType, @replacementTable); // 05/01/00 JES: use replacement table instead of a list
		replacementTable.mailaddress = args.mailaddress;
		if not defined (adruser^) {
			scriptError (mainResponder.getString ("members.checkMembershipWrongEmailAddress", @replacementTable, pta:adrParamTable))}; //PBS 08/31/00: pass pta // 4/14/00 JES: localized
		if not (string.upper (adruser^.password) == string.upper (string.urldecode (args.password))) {
			scriptError (mainResponder.getString ("members.checkMembershipWrongPassword", @replacementTable, pta:adrParamTable))}; //PBS 08/31/00: pass pta // 4/14/00 JES: localized
		local (cookieString = mainResponder.members.setCookie (args.mailaddress, args.password, adrmembers, adrparamtable, lookInGroup)); //PBS 04/10/00: send group name parameter to setCookie, which is a new optional parameter for that script
		adruser^.timeReceivedCookie = clock.now ()};
		<<fileMenu.saveMyRoot (adruser) //PBS 04/10/00: no need to save the root when someone logs in
		<<scriptError ("!redirect " + config.mainresponder.urls.memberHome)
	case adrparamtable^.method {
		"POST" {
			local (args);
			<<PBS 12/6/99: don't parse the POST args again, use the already-parsed POST args.
				<<If the already-parsed table doesn't exist, then *do* parse the POST args, but do it properly when the POST args are multi-part file uploads.
				<<This fixes the picture uploading bug reported by Manila users.
			if not defined (adrParamTable^.postArgs) {
				if string.lower (adrparamtable^.requestHeaders.["Content-type"]) beginsWith "multipart/form-data" {
					mainResponder.parseMultipart (adrParamTable)} //parse multipart form into adrparamtable^.postArgs
				else {
					local (adrtable = @adrparamtable^.postArgs);
					new (tabletype, adrtable);
					webserver.parseArgs (adrparamtable^.requestBody, adrtable)}};
			args = adrParamTable^.postArgs;
			local (formname = string.lower (adrparamtable^.pathargs)); //the stuff after the $ in the request
			case formname {
				"logonform" { //the user is requesting the cookie
					userRequestsCookie ()};
				"signupform" {
					with adrmembers^ {
						local (mailaddress = string.urldecode (args.mailaddress));
						mainresponder.members.sendMail (mailaddress, adrmembers, adrparamtable); //PBS 10/27/00: pass page table parameter
						adrparamtable^.mailAddress = mailaddress; //make it available to the logon macro
						<<adrobject = @parentof (adrobject^)^.checkYourMail //redirection, fast!
						scriptError ("!redirect " + adratts^.urls^.memberCheckMail + "$" + mailaddress)}};
				"superlogonform" { //one place to send them to, does everything, 3/9/99; 9:36:43 AM by DW
					<<it's called from whois.userland.com, so the user doesn't have to leave the home page to get the cookie
					local (mailaddress = string.urldecode (args.mailaddress));
					local (password = string.urldecode (args.password));
					if password == "" { //send password via email
						mainresponder.members.sendMail (mailaddress, adrmembers);
						scriptError ("!redirect " + adrparamtable^.requestheaders.referer + "$" + args.mailaddress)}
					else {
						userRequestsCookie ();
						scriptError ("!redirect " + adrparamtable^.requestheaders.referer)}}}
			else { // Tue, 23 Mar 1999 21:24:15 GMT by AR
				if not flMustBeMember {
					cookieRedirector ()} //gather the cookie info, won't actually redirect, legacy on legacy
				else {
					local (alist = string.parseaddress (parentof (adrobject^)), item, flpublic = false);
					for item in alist {
						if string.lower (item) == "public" { //no constraints on the public section
							flpublic = true;
							break}};
					if not flpublic {
						cookieRedirector ()}}}}} //if no cookie, redirect to the logon page
	else {
		if not flMustBeMember {
			cookieRedirector ()} //gather the cookie info, won't actually redirect, legacy on legacy
		else {
			local (alist = string.parseaddress (parentof (adrobject^)), item, flpublic = false);
			for item in alist {
				if string.lower (item) == "public" { //no constraints on the public section
					flpublic = true;
					break}};
			if not flpublic {
				cookieRedirector ()}}}} //if no cookie, redirect to the logon page



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.