I have been tearing my hair out for a few days looking at the code in /user/edit.php with a view to extracting the necessary code for adding a user.
The main problem was that it seemed to magically know the next available userid before any records were created. I have now managed to work out that the form gets the next available ID when the newuser=true getvar is sent.
However, I seem to have run into something potentially rather bad (confirmed with some brief testing)
If TutorA and TutorB both click through to add a new user, they will both receive the same next available ID.
As this ID does not seem to be reserved in any way, it is simply down to whomever happens to save their data last as to who gets to keep the ID for their user.
To be fair, it's hardly crippling as that situation should never occur for us; but i would imagine that it would get rather baffling for people who need to manually add users in this way!
Is this a known problem, or have I missed something here?
I think you will find that adding stuff to the database ultimately ends up calling insert_record() in datalib, and that takes care of assigning unique ids.
That was what I had hoped, unfortunately tests would tend to suggest otherwise.
I retested just now with the help of a colleague:
Both of our personal moodle users are moodle admins.
1. I (A) and my colleague (B) load the add a user page, and both receive the same userid.
2. A and B fill out their forms.
3. A submits their form, and the user account is created with the user id.
4. B submits their form, and the user account is inserted with the same id, effectively deleting the user created by A.
Can anyone recreate this? (I'm using Moodle 1.6)
I retested just now with the help of a colleague:
Both of our personal moodle users are moodle admins.
1. I (A) and my colleague (B) load the add a user page, and both receive the same userid.
2. A and B fill out their forms.
3. A submits their form, and the user account is created with the user id.
4. B submits their form, and the user account is inserted with the same id, effectively deleting the user created by A.
Can anyone recreate this? (I'm using Moodle 1.6)
He's right. I tried opening a window to create a new user, and here's the URL:
http://www.glyphdoctors.com/user/edit.php?id=2176&course=1
I opened another window to do the same thing, and here's the URL for that:
http://www.glyphdoctors.com/user/edit.php?id=2176&course=1
Since the user id is being assigned at the moment of loading the page, rather than when the data is sent to the database, I can see how it would easily overwrite.
Seems to me that everywhere else in Moodle id numbers are not assigned until submission, so maybe that needs to be the case for users as well.
http://www.glyphdoctors.com/user/edit.php?id=2176&course=1
I opened another window to do the same thing, and here's the URL for that:
http://www.glyphdoctors.com/user/edit.php?id=2176&course=1
Since the user id is being assigned at the moment of loading the page, rather than when the data is sent to the database, I can see how it would easily overwrite.
Seems to me that everywhere else in Moodle id numbers are not assigned until submission, so maybe that needs to be the case for users as well.
It is as you say.
The problem really seems to be that that is not actually an add user page, just an edit page with a special case for a new user called from the admin:
/admin/user.php?newuser=true&sesskey=abcdefghij
redirecing to ->
/user/edit.php?id=<next id>&course=1
Either this ID needs to be reserved somehow, or simply not created until the user account is. The latter seems like the best option, but I'm not really sure what would be most practical.
The problem really seems to be that that is not actually an add user page, just an edit page with a special case for a new user called from the admin:
/admin/user.php?newuser=true&sesskey=abcdefghij
redirecing to ->
/user/edit.php?id=<next id>&course=1
Either this ID needs to be reserved somehow, or simply not created until the user account is. The latter seems like the best option, but I'm not really sure what would be most practical.
Ok, I think I have some idea of what is going on.
The problem resides in /admin/user.php
Simply clicking the link for add user (calling /admin/user.php?newuser=true&sesskey=abcdefghij)
actually creates a new user - 'changeme' so if a second admin starts creating a user the code will find the changeme user and think that the second person created it when actually the first person is still editing it.
I tested this theory by appending the session key to the username:
"changeme-".$_GET['sesskey'];
This appears to solve the problem, but obviously creates the problem of orphaned changeme users for each session if the admin gives up half way through and never sets the user.
Confused? Me too!
I shall see if a neater solution presents itself otherwise I may have to call upon some more experienced Moodle developers!
P.S. I'm guessing I should sumbit this as a bug at some point?
The problem resides in /admin/user.php
Simply clicking the link for add user (calling /admin/user.php?newuser=true&sesskey=abcdefghij)
actually creates a new user - 'changeme' so if a second admin starts creating a user the code will find the changeme user and think that the second person created it when actually the first person is still editing it.
I tested this theory by appending the session key to the username:
"changeme-".$_GET['sesskey'];
This appears to solve the problem, but obviously creates the problem of orphaned changeme users for each session if the admin gives up half way through and never sets the user.
Confused? Me too!
I shall see if a neater solution presents itself otherwise I may have to call upon some more experienced Moodle developers!
P.S. I'm guessing I should sumbit this as a bug at some point?
P.S. I'm guessing I should sumbit this as a bug at some point?
Yes, right now would be a good time!
Yes, right now would be a good time!
Moodle forums have magic: just type "Bug 6291" and the link appears
Cool, thanks for the tip
Hi,
I don't know what you're trying to do... but, this discussion may help your efforts...
http://moodle.org/mod/forum/discuss.php?d=42699
-Geof
I don't know what you're trying to do... but, this discussion may help your efforts...
http://moodle.org/mod/forum/discuss.php?d=42699
-Geof
I simply needed to copy the Moodle code that creates a new user, which I notice is in the 'Student Adder' a bit less cryptically than in Moodle itself (see below), thanks for the pointer so I can build my own script that can be called from our Student Account Creation kiosk script - so that students will have their Moodle account setup at the same time as their Active Directory network account, managed printing account etc.
We are using LDAP auth, so we could use the ldap sync script but that leaves us in the same situation as we were in with WebCT - no way of guaranteeing a student will be able to login to Moodle after having just filled out the account creation form.
Unfortunately, in so doing I discovered that the Moodle code itself isn't quite perfect. So I got sidetracked working out what it was doing wrong and reporting the bug.
On the plus side i'm now fairly happy with how database records are created and therefore how user accounts should be created.
Oh for a central API, or even... Web Services
We are using LDAP auth, so we could use the ldap sync script but that leaves us in the same situation as we were in with WebCT - no way of guaranteeing a student will be able to login to Moodle after having just filled out the account creation form.
Unfortunately, in so doing I discovered that the Moodle code itself isn't quite perfect. So I got sidetracked working out what it was doing wrong and reporting the bug.
On the plus side i'm now fairly happy with how database records are created and therefore how user accounts should be created.
Oh for a central API, or even... Web Services
//Create a new user.
$newuser->auth = 'manual';
$newuser->confirmed = 1;
$newuser->policyagreed = 0;
$newuser->deleted = 0;
$newuser->username = $name;
$newuser->password = $password;
$newuser->firstname = $fstname;
$newuser->lastname = $lname;
$newuser->email = $email;
$newuser->emailstop = 0;
$newuser->department = $mydepartment;
$newuser->city = $mycity;
$newuser->country = $mycountry;
$newuserid = insert_record('user', $newuser);
Hi Alastair, I'm confused about this:
We are using LDAP auth
If you are using LDAP auth, Moodle checks with your LDAP server whenever someone trys to login. If your account creation form pushes student data to your LDAP server when users are created, the student should be able to login to Moodle immediately when using LDAP auth.
We are using LDAP auth
If you are using LDAP auth, Moodle checks with your LDAP server whenever someone trys to login. If your account creation form pushes student data to your LDAP server when users are created, the student should be able to login to Moodle immediately when using LDAP auth.
Hi Michael,
The problem with not being able to login to Moodle immediately would only occur if we used just the ldap sync script, and not the solution you have described above (a bit more succinctly than me!)
So in short, problem solved.
Hope that makes sense this time
The problem with not being able to login to Moodle immediately would only occur if we used just the ldap sync script, and not the solution you have described above (a bit more succinctly than me!)
So in short, problem solved.
Hope that makes sense this time