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]
-----Original Message-----
From: Sergiu Dumitriu [mailto:sergiu.dumitriu@gmail.com]
Sent: Wednesday, February 21, 2007 5:31 AM
To: xwiki-users(a)objectweb.org
Subject: Re: [xwiki-users] CookieMonster
On 2/20/07, THOMAS, BRIAN M (ATTSI) <bt0008(a)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