SOC Progress on "User Manager for SWAT (Samba 4)"

tridge at samba.org tridge at samba.org
Mon Sep 4 06:12:57 GMT 2006


Sree,

Here are some comments on your user_manager gui code before I forget them!

I hit a few snags getting the code to work at first. The first snag
was that SWAT was failing to authenticate. That turned out to be a
problem with a recent change in the ldb partitioning code. After some
discussions with Andrew and Simo we fixed that up with the change that
makes ldb look in the rootDSE for the defaultNamingContext. That got
the ejs auth code working again with the new partitions system, and as
a nice side effect simplified some other code.

That problem raised an interesting point though - we need some way to
automatically test SWAT in 'make test', so we discover these sorts of
problems more quickly! It's something we need to think about :-)

The next snag I hit was that the user manager showed up an empty list
of users, even though I knew there were several users defined. This
was quite hard to track down. The problem with tracking it down is
that AJAX (as currently implemented in Samba4) makes it hard to debug
problems, as often you just get no result.

You can't just attach with gdb and I've never had much joy with js
debuggers and complex callbacks, so I needed a sane way to do printf()
or equivalent calls in in the client js code, so I could tell what was
going on. We already have a srv_printf() call which does a printf()
into the servers log file from a bit of client js, but as I wanted to
debug the js async mechanisms themselves I needed to hack it like
this:

--- swat/scripting/client/call.js	(revision 18025)
+++ swat/scripting/client/call.js	(working copy)
@@ -49,6 +49,9 @@
 	object. 'callback' may be null.
 */
 function vserver_call_url(url, func, callback, args) {
+	if (func != "srv_printf") {
+		srv_printf("url=%s func=%s\n", url, func);
+	}
 	var args2 = new Object();
 	args2.length = args.length;
 	var i;
@@ -59,8 +62,15 @@
 	req.open("POST", url, true);
 	req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
 	req.send("ajaj_func=" + func + "&ajaj_args=" + encodeObject(args2));
+	if (func != "srv_printf") {
+		srv_printf("url=%s func=%s encoded=%s\n", url, func, 
+			   encodeObject(args2));
+	}
 	req.onreadystatechange = function() { 
 		if (4 == req.readyState && callback != null) {
+			if (func != "srv_printf") {
+				srv_printf("decoding=%s\n", req.responseText);
+			}
 			var o = decodeObject(req.responseText);
 			callback(o.res);
 		}
@@ -86,6 +96,7 @@
 		args[i-3] = arguments[i];
 	}
 	args.length = i-3;
+	srv_printf("server_call_url url=%s func=%s\n", url, func);
 	vserver_call_url(url, func, callback, args);
 }
 

The nasty if() statements meant I could call srv_printf() from within
srv_printf(), allowing me to see the flow of calls. That got me a bit
further with debugging. I then found that what was going on was that
the ejs interpreter was dying with an error that it was unable to find
one of its include files. It was dying with a backtrace, but this
backtrace wasn't getting displayed on the web browser. We really need
a better error reporting mechanism!

Anyway, after fixing up the include line, I got a list of users! So,
now some comments on your real code, and not just comments on my
crappy AJAX infrastructure code .....

I noticed that the user browser window wouldn't grow or scroll
correctly. It also starts off quite small (at least on my screen) but
maximising it doesn't work well. I had a look at how it works, and
what struck me is that the js code in userbrowser.js is a bit too hard
coded, and not abstracted enough. It does things like directly
constructing a QxListView(), a QxBoxLayout(), menu, window etc. That
works ok for a demo, but I think it would be better to construct a
higher level widget handles all the details for a multi-column list
with callbacks attached to a set of ldb records, and keep all that low
level gui code quite separate from userbrowser.js. The userbrowser.js
code would become much simpler, and would just be a consumer of this
widget, just passing in a list of attributed that can be read/written
etc. Deryck might have more comments on the best way to approach this?

I played a bit with changing user properties, and sometimes got an
error when doing things like changing the user description. The
strange thing is that the description did change, even though it
displayed an error. It seemed to be a problem with strings turning up
as object pointers and trying to commit those into the database?

It also showed another problem with error reporting. The usual error
message was "Could not update properties" in a alert box, but no
reason was given for why the properties could not be updated. We have
to make sure that we propogate any ldb errors back to the user, so
they at least have a chance of working out why something went
wrong. Ideally we'd even have a little 'details' button on the error
display which would expand to the ldif we were trying to use in the
ldb operation (presuming it was an operation that takes ldif, like a
modify). 

To make this work, I think the server side functions in usermgmt.esp
should return a js object containing details of both the request and
the result. So at the moment you have:

    r = sam.ldb.transaction_commit();
    return r;

which means we only get the integer result of the transaction
commit. If instead it returned an object containing an 'ecode' member
(from the transaction commit) plus some details on the operation (name
of operation, copy of ldif etc) then the error box could supply a
useful amount of information on what went wrong.

One thing that puzzles me is the fact that when I got the error
message from a properties change, it did still change at least some of
the properties (ie. when I did a refresh the change showed up). That
is bad! It means something is going wrong with the transaction code,
either in how we are calling it, or in the ldb/tdb code itself. The
point of transactions is that either it all works, or nothing changes,
so to see something partly working worries me! We need to look into
this.

I'd also be interested in any comments you may have on developing with
Qooxdoo. I've been a bit disappointed at how little of the ui
mechanics is handled by Qooxdoo. I was rather hoping it might take
care of more of the details :)

Cheers, Tridge


More information about the samba-technical mailing list