Call to POST to https://graph.microsoft.com/v1.0/me/events not working - calendar

I tried search most of today and not finding the root of my issue. I registered an app and copied the ids as needed to make calls to the Microsoft Graph API.
On making a GET call to users/xxxxxxx-f192-4758-xxxx-3f1c27ee5ef9/events, I do get back all my events in the Calendar.
But the issue is, when making a POST call to me/events using the data below:
$calendarEventData = array
(
'subject' => 'Test event in my calendar',
'start' => array
(
'dateTime' => '2020-12-22T15:14:14.524Z',
'timeZone' => 'UTC'
),
'end' => array
(
'dateTime' => '2020-12-22T17:14:14.524Z',
'timeZone' => 'UTC'
),
'body' => array
(
'content' => 'This is some hard coded body content',
'contentType' => 'text'
)
);
I get back a HTTP/1.1 403 Forbidden returned for "https://graph.microsoft.com/v1.0/me/events". I have ensure that the API permissions for Calendars.ReadWrite does exist and consent has been granted too (even redid that to seee if that makes a difference)
Please advise where I am going wrong?
Thank you

The problem may be caused by you assign the permission Calendars.ReadWrite in Application type(but not Delegated type) and you use client credential flow to do authentication. As client credential flow doesn't require you input username and password, so the access token will not contain the user information. When you request the api https://graph.microsoft.com/v1.0/me/events, the api backend don't know who is me. So it shows 403 error message.
To solve this problem, you can use the object id of "me" to replace me in your request api. Like POST https://graph.microsoft.com/v1.0/{user object id}/events.

Related

CakePHP 3 - How to check whether an Email has been delivered successfully?

i am trying to sending mail using cakephp 3.0 .
My code is :
Email::configTransport('WebMail',[
'className' => 'Smtp',
'host' => $host,
'port' => $port,
'timeout' => 30,
'username' => $username,
'password' => $password,
'client' => null,
'tls' => null]
);
$transport = ['transport' => 'WebMail'];
$email = new Email($transport);
$email
->from([$username => $senderName])
->to($email_to)
->subject('Password Reset Code');
$response = $email->send('hello');
its working fine but the problem is how to check if the email was delivered successfully or not to the recipient.
if I debug $response variable I got the array of all mail related data.
Now how can I check if the email was delivered or not .
You can't... at least not reliably. All CakePHP can tell you is whether sending/queing the mail was successful, and depending on the transport (Smtp/Mail/...) that you're using you can get the last response received from the E-Mail server.
If sending/queing was unsuccessful, a \Cake\Network\Exception\SocketException exception will be thrown, so catch that if you want to evaluate this problem. Other than that there's no further information CakePHP/PHP can provide you with.
try {
$email->send();
} catch (\Cake\Network\Exception\SocketException $exception) {
// sending/queing failed
// the last response is available when using the Smtp transport
$lastResponse = $email->transport()->getLastResponse();
}
If applicable you could use a custom Smtp transport and implement requesting DSNs (Delivery status notifications, which you could then evaluate later on, however this isn't foolproof either, as notifications aren't guaranteed.
See also
API > \Cake\Mailer\Transport\SmtpTransport::getLastResponse()
API > \Cake\Mailer\Email::transport()
You'll need to add some form of tracking pixel to the email, or just use a transactional email service like Mandrill (MailChimp) or SendGrid...etc that will do this for you. You can then see whether they received it, and if they opened it...etc.
You can manually open the inbox of sending email to check if the mail was sent. If due to any reason the mail could not be sent, you'll receive a revert mail stating the problem.
Now, I know this is not a very efficient method so you need to keep these things in mind :-
1. You need to lower the security of your email.
2. You should not send codes (JavaScript etc) on email.
3. Keep in mind the size of content you are sending.
With these points checked you can assume your mail was sent. For a safer side you can check you mail once a week/month to see if all the mails were sent or if you got any error.

Email is not going to deliever on yahoo server

I am using cakephp, and sending email through cakeemail with smtp. My hosting is on 1and1.com. Email is going to deliver on gmail but not on yahoo and hotmail.
Then I try the PHPMailer on same server and its email was going to deliver on gmail and hotmail as well. But unfortunatly I am unable to use PHPMailer with cakephp. I have try two tutorial but fails. One of them is here.
I will prefer to fix the problem with cakeemail, if some one can help regarding this.
Or if can get solution with PHPMailer for cakephp that is also ok.
Here is the my code
$email = new CakeEmail();
$email->smtp = array(
'port'=>'25',
'timeout'=>'30',
'host' => 'smtp.1and1.com',
'username'=>'quote#xxxxxx.com',
'password'=>'xxxxxx_',
'client' => 'smtp.1and1.com' ,
'transport' => 'Smtp'
);
$email->from(array('xxxx#a-xxxx.com' => 'A-Best Auto Parts Quote'));
$email->to("xxxx#yyy.com");
//$email->bcc("xxxx#yyy.com");
$email->subject('My Test Subject');
$email->emailFormat('html');
$body="the test message for email"
$email->send($body);

What are scope values for an OAuth2 server?

I'm facing a difficulty to understand how scopes work.
I found here a small text that describes the scopes of stackexchange api but i need more information on how they work (not specifically this one...). Can someone provide me a concept?
Thanks in advance
To authorize an app you need to call a URL for the OAuth2 authorization process. This URL is "living" in the API's provider documentation. For example Google has this url:
https://accounts.google.com/o/auth2/auth
Also you will need to specify a few query parameters with this link:
cliend_id
redirect_uri
scope: The data your application is requesting access to. This is typically specified as a list of space-delimited string, though Facebook uses comma-delimited strings. Valid values for the scope should be included in the API provider documentation. For Gougle Tasks, the scope is https://www.googleapis.com/auth/tasks. If an application also needed access to Google Docs, it would specify a scope value of https://www.googleapis.com/auth/tasks https://docs.google.com/feeds
response_type: code for the server-side web application flow, indivating that an authorization code will be returned to the application after the user approves the authorization request.
state: A unique value used by your application in order to prevent cross-site request forgery (CSRF) attacks on your implementation. The value should be a random unique string for this particular request, unguessable and kept secret in the client (perhaps in a server-side session)
// Generate random value for use as the 'state'. Mitigates
// risk of CSRF attacks when this value is verified against the
// value returned from the OAuth provider with the authorization
// code.
$_SESSION['state'] = rand(0,999999999);
$authorizationUrlBase = 'https://accounts.google.com/o/oauth2/auth';
$redirectUriPath = '/oauth2callback.php';
// For example only. A valid value for client_id needs to be obtained
// for your environment from the Google APIs Console at
// http://code.google.com/apis/console.
$queryParams = array(
'client_id' => '240195362.apps.googleusercontent.com',
'redirect_uri' => (isset($_SERVER['HTTPS'])?'https://':'http://') .
$_SERVER['HTTP_HOST'] . $redirectUriPath,
'scope' => 'https://www.googleapis.com/auth/tasks',
'response_type' => 'code',
'state' => $_SESSION['state'],
'approval_prompt' => 'force', // always request user consent
'access_type' => 'offline' // obtain a refresh token
);
$goToUrl = $authorizationUrlBase . '?' . http_build_query($queryParams);
// Output a webpage directing users to the $goToUrl after
// they click a "Let's Go" button
include 'access_request_template.php';
The set of query string parameters supported by the Google Authorization Server for web server applications are here:
https://developers.google.com/accounts/docs/OAuth2WebServer?hl=el#formingtheurl

Perform user token check in CakePHP API routes

I'm creating an API, and I'm wondering what the best practice is to check a user token.
Here's an example of the paths I'm using and its accompanying rule:
http://www.domain.com/api/user/ede12-snip-f50b9/project/1
Router::connect(
"/api/user/:token/project/:projectid/issues",
array("action" => "issues", "controller" => "projects", "[method]" => "GET"),
array("id" => "[0-9]+", 'pass' => array('token', 'projectid'))
);
This works, but then I have to check the token credentials in every action. And I don't want that.
Does anyone know of another way?
This works, but then I have to check the token credentials in every action. And I don't want that.
If your API is stateless there is no other way.

CakePHP 403 on AJAX request

I'm trying to use AJAX to autocomplete a search box on my website. I was using firebug to test my application. When I try to search something, Firebug tells me that the AJAX request returned a 403 forbidden error. However, when I copy the EXACT URL that was in the AJAX request, it returns the correct data.
Edit:
I think this has to be something on the JavaScript side. Are there any headers that might be omitted with an AJAX request compared to a normal request?
Here is the $_SERVER variable (I removed the parameters that were the same on both requests) on an AJAX request that failed (1) vs typing the URL in and it works (2):
(1)
2011-04-02 13:43:07 Debug: Array
(
[HTTP_ACCEPT] => */*
[HTTP_COOKIE] => CAKEPHP=0f9d8dc4cd49e5ca0f1a25dbd6635bac;
[HTTP_X_REQUESTED_WITH] => XMLHttpRequest
[REDIRECT_REDIRECT_UNIQUE_ID] => TZdgK654EmIAAEjknsMAAAFG
[REDIRECT_UNIQUE_ID] => TZdgK654EmIAAEjknsMAAAFG
[REMOTE_PORT] => 60252
[UNIQUE_ID] => TZdgK654EmIAAEjknsMAAAFG
[REQUEST_TIME] => 1301766187
)
(2)
2011-04-02 13:44:02 Debug: Array
(
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[HTTP_COOKIE] => CAKEPHP=d8b392a5c3ee8dd948cee656240fd5ea;
[REDIRECT_REDIRECT_UNIQUE_ID] => TZdgYq54EmIAAF7zt6wAAAJJ
[REDIRECT_UNIQUE_ID] => TZdgYq54EmIAAF7zt6wAAAJJ
[REMOTE_PORT] => 60281
[UNIQUE_ID] => TZdgYq54EmIAAF7zt6wAAAJJ
[REQUEST_TIME] => 1301766242
)
I think I found the solution. I set the security level to medium to solve the issue. I found this line in the config folder. Does a medium security level pose any problems in production?
/**
* The level of CakePHP security. The session timeout time defined
* in 'Session.timeout' is multiplied according to the settings here.
* Valid values:
*
* 'high' Session timeout in 'Session.timeout' x 10
* 'medium' Session timeout in 'Session.timeout' x 100
* 'low' Session timeout in 'Session.timeout' x 300
*
* CakePHP session IDs are also regenerated between requests if
* 'Security.level' is set to 'high'.
*/
Configure::write('Security.level', 'medium');
Edit: This is definitely the solution. Here's what was happening:
When the security level is set to high, a new session ID is generated upon every request.
That means that when I was making ajax requests, a new session ID would be generated.
If you stay on the same page, JavaScript makes a request, which generates a new session_id, and doesn't record the new session_id.
All subsequent ajax requests use an old session_id, which is declared invalid, and returns an empty session.
If you are using Auth, you need to make sure that you are logged in if the controller/action is not on your $this->Auth->allow() list.
Make sure you set debug to 0 as well, might cause you some problems.
Maybe it's the Cross site request forgery component. It's responsible for all authentication requests, except GET requests. Look at this: http://book.cakephp.org/3.0/en/controllers/components/csrf.html

Resources