Two
things (not related to why I titled my message
CookieMonster):
First: Thanks, Sergiu, for the information, and the HTTP
status code idea sounds good, although it may cause other people heartburn who
expect a properly-rendered page to return HTTP_OK. I haven't looked at all
the protocol's status codes thoroughly, though, and there might be some codes
that are appropriate for an application error, and in particular,
HTTP_UNAUTHORIZED(401) would probably be appropriate here. The biggest
problem I had was how, from within a filter, to establish the authority to
register a user.
I
probably don't need to comment on the appropriateness of using GET methods to
effect changes; from the look of things the choice was probably a quick hack to
get things done, since other update operations are not done that way. I do
note that there is a "register" action path in the deployment descriptor, though
the register link doesn't use it (and not only is register.vm written explicitly
in French but it doesn't display the XWiki.XWikiUsers object's content), instead
using "view" for a form submission, which apparently must use GET, because when
I tried using POST, although I didn't get any errors, it didn't work and I
abandoned the approach, mostly because I suspected that a lack of permission was
to blame.
Second: I did succeed in getting the correct context set, and the
auto-registration from within the filter is now working quite well. Since
it's easier to show than tell, here's the relevant code:
private void setXWikiToRights(CSPCookieRequestWrapper req,
HttpServletResponse rsp) throws ServletException {
XWiki xwiki = null;
XWikiContext context =
null;
try {
/* this is
a desperate attempt to get the correct context set
* for
XWiki in order to synch user privileges
*/
ServletContext sctx = req.getSession().getServletContext();
context =
Utils.prepareContext("view",
new
XWikiServletRequest(req),
new
XWikiServletResponse(rsp),
new
XWikiServletContext(sctx));
xwiki =
XWiki.getXWiki(context);
}
catch (XWikiException e2) {
throw new
ServletException("can't find XWiki instance", e2);
}
Map attrs = new HashMap();
Map authInfo =
req.getUserPrincipal().getMap();
String content = "#includeForm(\"XWiki.XWikiUserSheet\")";
String userName =
(String)authInfo.get(CSPCookieFilter.CSP_ATT_UID);
attrs.put("email",
authInfo.get(CSPCookieFilter.CSP_HR_EMAIL));
attrs.put("first_name",
authInfo.get(CSPCookieFilter.CSP_HR_FIRST_NAME));
attrs.put("last_name",
authInfo.get(CSPCookieFilter.CSP_HR_LAST_NAME));
try {
xwiki.createUser(userName, attrs, "XWiki.WebHome", content, "edit",
context);
} catch
(XWikiException e) {
throw new
ServletException("creating new user", e);
}
}
As you
suggested, I had indeed started with XWikiAction (or XWikiRequestProcessor, I
forget which). The critical component was Utils.prepareContext which
depended only on information I had readily to hand (well, almost; I had to
modify the method signatures to pass in the response object, which had not
previously been needed).
I
don't check for the existence of the user first, since createUser does that
anyway, and more efficiently than I could, so I just invoke it unconditionally
and ignore the return code. I probably should also ignore any exceptions
too, counting on XWiki to handle any resulting problems.
For
another approach, the generic "synch filter" I described earlier, which simply
sends a message with all of the parsed cookie values as tag-value pairs, might
have worked with an XMLRPC request, but as with the "view" request to the
RegisterNewUser page, I had a problem figuring out how to establish the
necessary authority from within the filter.
Generally, I think I agree that an HTTP request would be the best way to
proceed; I just can't figure out how to get that authorization, since the filter
can't assert any special identity from the client end of an HTTP connection
merely because of its situation within the server itself. Allowing
XWikiGuest to have "view" access to the registration page would seem to be
a bad idea since, despite its security implications, that's what
registration entails. I think I smell JIRA here...
brain[sic]
On 2/20/07, THOMAS,
BRIAN M (ATTSI) <bt0008@att.com>
wrote:
I
apologize for the length of this message, but it's a topic that I
believe
to be of pretty wide interest and takes some explaining.
[snip]
The
first approach would have required a custom form, and it looked
hard
enough that I didn't try it, but most of all I couldn't work out how
to
get the correct permissions. Between that and the second, I
created a
URL object with which I formatted a GET request to
the
XWiki.RegisterNewUser page. That had significant problems,
chief of
which was determining whether the registration had actually
worked - the
HTTP status doesn't tell you, and I'd have to parse the
response to
guess the answer. Changing the form (which I had
to do anyway) would
make that easier, but I didn't like that answer
either.
We're already working on adding meaningful HTTP status codes. In a
few days (if you want this) we can make registration return the proper status
code. And I don't think you need to write a form, the right GET URL should
work just fine.
So,
in short:
1) Where, if anywhere, can I jump into the XWiki
APIs to initialize
the context properly? and/or
Try looking inside .../xwiki/web/XWikiAction , that's a good starting
point. Right now I'm in a hurry, so I don't have time to check
myself.
2)
If this is a stupid way to approach the problem, what would be a
wiser
one?
If the registration page would return status codes, I'd say it is
better to create a request.
Thanks
in advance, as always,
brain[sic]
Sergiu
Dumitriu
--
http://purl.org/net/sergiu