LafColITS / Moodle-auth_casattras

A CAS (SSO) authentication module for Moodle that uses releaseed attributes rather than LDAP for user-information.
10 stars 13 forks source link

mb_substr(): Argument #1 ($string) must be of type string, array given #41

Open tomas-nikl opened 1 year ago

tomas-nikl commented 1 year ago

CAS returns the values of some attributes as an array. The plugin cannot split the field into parts and use the first or other of the returned values. Error occurs: mb_substr(): Argument #1 ($string) must be of type string, array given. It would be desirable that the attribute whose values are located in the field e.g. "MAIL" and which contains multiple values e.g. [myaddress1@lf1.cuni.cz, myaddress2@ruk.cuni.cz] could be mapped to a value in the settings in the field, for example: "MAIL[0]" or "MAIL[1]".

mackensen commented 1 year ago

I think if you were going to pass multiple mail attributes I'd expect CAS to release them to that service under different names, rather than having Moodle interpret the parts of an array. Is it a common use case at your institution to have multiple values in the mail attribute?

tomas-nikl commented 1 year ago

Our CAS server returns all attributes that take on multiple values under the same name as the array. It's not just an email. Below I give an example of listing attribute values. Those with multiple values are returned as an array.

Attribute | Value(s)

cn | [Name Surname] cuniauthorizedmail | [name.surmane@lf1.cuni.cz, name.suname@ruk.cuni.cz] cunimailverificationexpiration | [20230327104047Z] cunipersonalid | [74554551548545243] cuniprincipalname | [NIKLT] cuniscopedaffiliation | [staff@org130.ukn.cuni.cz, staff@org1473.lf1.cuni.cz] edupersonscopedaffiliation | [staff@ukn.cuni.cz, staff@lf1.cuni.cz] email | [name.surmane@lf1.cuni.cz, name.surmane@ruk.cuni.cz] email_verified | [true] givenname | [Name] mail | [name.surmane@lf1.cuni.cz, name.surmane@ruk.cuni.cz] mobile | [+420777101166, +420777128385] sn | [Surmane] telephonenumber | [+420224491714] uid | [75185243, surnameN]

tomas-nikl commented 1 year ago

A fellow programmer discovered a place in your PHP script where attributes are read from the CAS server and inserted the code below into that place. The code checks if the received value is an array. If so, then it is divided into individual strings and the first position from the array is inserted into the value of the mapped attribute. In this modified form, CAS authentication works for us.

if(is_array($casattras[$field]) $moodleattras[$key] = $casattras[$field][0]; else $moodleattras[$key] = $casattras[$field];

mackensen commented 1 year ago

I think that's a reasonable way to solve the issue, with the caveat that taking the first value could cause unexpected behavior if the CAS server ever returns them in a different order.

tomas-nikl commented 1 year ago

If the server returned the values in a different order (and this does not happen on our CAS yet), then a different user account would be created for the user. There would be two users with the same first name, last name, ID and different e-mail in the list of users. I am considering the case when we map the values of the First Name, Last Name, ID, and Email attributes, which are sufficient for us to create an account.

Would it be possible in the next versions of your module to implement the identification of incoming array data types and their subsequent handling so that errors do not occur as in our case? Thank you very much for your cooperation and efforts to solve the problem.