microsoft / o365-moodle

Office 365 and Azure Active Directory plugins for Moodle
GNU General Public License v3.0
184 stars 138 forks source link

Error in API call #2623

Closed cbrherms closed 2 months ago

cbrherms commented 3 months ago

Newly upgraded moodle installation to 4.3.6, with corresponding o365 plugin (4.3.5). Now getting a lot of errors in the logs that i'm unable to find the source of.

Event context Component Event name Description Origin
System Microsoft 365 Integration API failure Cannot retrieve a token for the base resource. cli

As far as i can tell, all permissions are correct on our Azure/Entra app and admin consent has been granted.

I have noticed that Microsoft Entra tenant detection now detects as our main domain name rather than our .onmicrosoft.com address, and the OneDrive for Business URL won't automatically detect: "We could not determine your OneDrive for Business URL, please enter manually."

Not sure if this is related. Though everything checks out when using the "verify setup" button.

Does anyone have any thoughts?

cbrherms commented 3 months ago

Looking in to it a bit further, logstore logs in the db are showing that it's 3 processes erroring on the token, though their scheduled logs are showing as successful. issues are with calsync\task\importfromoutlook, classes\task\processmatchqueue, and classes\task\coursesync.

{"message":"Cannot retrieve a token for the base resource.","where":"local_o365\\oauth2\\token::instance","debugdata":null,"backtrace":[{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/oauth2\/token.php","line":174,"function":"debug","class":"local_o365\\utils","type":"::","args":["Cannot retrieve a token for the base resource.","local_o365\\oauth2\\token::instance"]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/utils.php","line":104,"function":"instance","class":"local_o365\\oauth2\\token","type":"::","args":[null,"https:\/\/graph.microsoft.com",{},{"cache":false,"proxy":false,"version":"0.4 dev","response":[],"rawresponse":[],"header":[],"info":null,"error":null,"errno":null,"emulateredirects":true,"_tmp_file_post_params":[]},false]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/utils.php","line":76,"function":"get_application_token","class":"local_o365\\utils","type":"::","args":["https:\/\/graph.microsoft.com",{},{"cache":false,"proxy":false,"version":"0.4 dev","response":[],"rawresponse":[],"header":[],"info":null,"error":null,"errno":null,"emulateredirects":true,"_tmp_file_post_params":[]}]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/feature\/calsync\/task\/importfromoutlook.php","line":53,"function":"is_connected","class":"local_o365\\utils","type":"::","args":[]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":405,"function":"execute","class":"local_o365\\feature\\calsync\\task\\importfromoutlook","object":{},"type":"->","args":[]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":208,"function":"run_inner_scheduled_task","class":"core\\cron","type":"::","args":[{}]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":125,"function":"run_scheduled_tasks","class":"core\\cron","type":"::","args":[1724897761,1724897582]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/admin\/cli\/cron.php","line":186,"function":"run_main_process","class":"core\\cron","type":"::","args":["180"]}]}
{"message":"Cannot retrieve a token for the base resource.","where":"local_o365\\oauth2\\token::instance","debugdata":null,"backtrace":[{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/oauth2\/token.php","line":174,"function":"debug","class":"local_o365\\utils","type":"::","args":["Cannot retrieve a token for the base resource.","local_o365\\oauth2\\token::instance"]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/utils.php","line":104,"function":"instance","class":"local_o365\\oauth2\\token","type":"::","args":[null,"https:\/\/graph.microsoft.com",{},{"cache":false,"proxy":false,"version":"0.4 dev","response":[],"rawresponse":[],"header":[],"info":null,"error":null,"errno":null,"emulateredirects":true,"_tmp_file_post_params":[]},false]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/utils.php","line":76,"function":"get_application_token","class":"local_o365\\utils","type":"::","args":["https:\/\/graph.microsoft.com",{},{"cache":false,"proxy":false,"version":"0.4 dev","response":[],"rawresponse":[],"header":[],"info":null,"error":null,"errno":null,"emulateredirects":true,"_tmp_file_post_params":[]}]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/task\/processmatchqueue.php","line":85,"function":"is_connected","class":"local_o365\\utils","type":"::","args":[]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":405,"function":"execute","class":"local_o365\\task\\processmatchqueue","object":{},"type":"->","args":[]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":208,"function":"run_inner_scheduled_task","class":"core\\cron","type":"::","args":[{}]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":125,"function":"run_scheduled_tasks","class":"core\\cron","type":"::","args":[1724897702,1724897582]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/admin\/cli\/cron.php","line":186,"function":"run_main_process","class":"core\\cron","type":"::","args":["180"]}]}
{"message":"Cannot retrieve a token for the base resource.","where":"local_o365\\oauth2\\token::instance","debugdata":null,"backtrace":[{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/oauth2\/token.php","line":174,"function":"debug","class":"local_o365\\utils","type":"::","args":["Cannot retrieve a token for the base resource.","local_o365\\oauth2\\token::instance"]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/utils.php","line":104,"function":"instance","class":"local_o365\\oauth2\\token","type":"::","args":[null,"https:\/\/graph.microsoft.com",{},{"cache":false,"proxy":false,"version":"0.4 dev","response":[],"rawresponse":[],"header":[],"info":null,"error":null,"errno":null,"emulateredirects":true,"_tmp_file_post_params":[]},false]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/utils.php","line":76,"function":"get_application_token","class":"local_o365\\utils","type":"::","args":["https:\/\/graph.microsoft.com",{},{"cache":false,"proxy":false,"version":"0.4 dev","response":[],"rawresponse":[],"header":[],"info":null,"error":null,"errno":null,"emulateredirects":true,"_tmp_file_post_params":[]}]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/local\/o365\/classes\/task\/coursesync.php","line":53,"function":"is_connected","class":"local_o365\\utils","type":"::","args":[]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":405,"function":"execute","class":"local_o365\\task\\coursesync","object":{},"type":"->","args":[]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":208,"function":"run_inner_scheduled_task","class":"core\\cron","type":"::","args":[{}]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/lib\/classes\/cron.php","line":125,"function":"run_scheduled_tasks","class":"core\\cron","type":"::","args":[1724897642,1724897521]},{"file":"\/var\/www\/my.moodledomain.ac.uk\/public_html\/admin\/cli\/cron.php","line":186,"function":"run_main_process","class":"core\\cron","type":"::","args":["180"]}]}

Any insight would be appreciated.

weilai-irl commented 2 months ago

Hi @cbrherms

The Microsoft Entra tenant detection feature will try to determine your primary domain name, so if you have multiple custom domains and the .onmicrosoft.com one hasn't been set as the primary, this is expected results. You can go to https://portal.azure.com/#view/Microsoft_AAD_IAM/DomainsList.ReactView to check your domains.

I have noticed myself that some times that detecting "OneDrive for Business URL" doesn't work. I think it's minor issue, but I have yet looked into it. This should be less concerning issue, as the URL is mainly used to show links in the Microsoft block. It should be safe enough to set it manually.

Now the big issue are the token errors. The functions would use application tokens to call Microsoft Graph APIs, so most logic related to the token should be in https://github.com/microsoft/o365-moodle/blob/MOODLE_403_STABLE/local/o365/classes/oauth2/apptoken.php.

The first thing you may want to check is whether there are application tokens stored in the database. The DB query is SELECT * FROMmdl_config_pluginsWHERE plugin = 'local_o365' AND name = 'apptokens';

Since you have got expected results when clicking the verify setup button, you should have created and stored an application token in the DB already. The query is expected to return 1 row, with the "value" column storing a serialised string. Unserialise it should give you an array of application tokens. It's expected that there is only one token, with "https://graph.microsoft.com" as key. The "token" attribute of the token record should contains a JWT token. Decoding the token should show a "role" claim, containing all the app permissions that the token has. This should be the same as you have given admin consent to the Azure app in Azure portal. See the images attached for an example stored token structure, and the "role" claim values.

Unserialised token App token role claim

If you don't have these records, you can delete the stored app tokens from Moodle database if it presents, then you need to verify Azure app permissions, grant admin consent in Azure port, grant admin consent in Moodle, and verify the setup again. After these steps, you should have the expected token records.

Please follow these steps to create the correct token records, and retry the actions to see if the error still exists.

If these are still not working, please read on.

Whenever the plugins need to call Microsoft Graph APIs, it will try to find a stored application token. If none is found, it will try to create one. If you see the "Cannot retrieve a token for the base resource." error, it means the attempt to create a new application token failed. You will need to find out the raw response of the request trying to create an application token. The code is at https://github.com/microsoft/o365-moodle/blob/591e1debc7ce7f97129d06e3c3b28cbe369e47c2/local/o365/classes/oauth2/apptoken.php#L118. Please add var_dump($tokenresult); die; after line 118, start a new action that may trigger the error, and monitor the results. It may contain the key to the error.

Please investigate on your end and post back updates.

Regards, Lai

cbrherms commented 2 months ago

Hi @weilai-irl ,

I appreciate the detailed response.

Can confirm i've only one token result from the DB query, and after decoding it has all the same roles as your example. Only difference is I also have in addition: EduRoster.Read.All TeamSettings.Read.All

Having added in the vardump line, it appears I cannot get the error to trigger, and looking back it seems that the errors stopped earlier in the month so something somewhere must have been changed, or kicked things back in to gear.

Will close this issue for now and reopen if I see this issue again.