Error adding new event to google calender Google_Service_Exception (401) { "error": "unauthorized_client", "error_description": "Unauthorized" } - laravel

When i try to submit a new event to my google calender in a laravel project I always face this error:
Google_Service_Exception (401)
{ "error": "unauthorized_client", "error_description": "Unauthorized" }
I created new OAuth credentials for calendar api and added it to .env file as shown:
I am also using google+ api so that each user can access his calender to update his events via OAuth 2
I tried to add new OAuth credentials but the problem still persist I also tried to delegate domain-wide authority to my service account by adding client id added to the .env file & scope and authorize them but nothing changed I also waited for 24 hours waiting the changes to take place but also nothing changed
Here is the function am using to create new events:
public function doCreateEvent(Event $evt, Request $request)
{
$this->validate($request, [
'title' => 'required',
'calendar_id' => 'required',
'datetime_start' => 'required|date',
'datetime_end' => 'required|date'
]);
$title = $request->input('title');
$calendar_id = $request->input('calendar_id');
$start = $request->input('datetime_start');
$end = $request->input('datetime_end');
$start_datetime = Carbon::createFromFormat('Y/m/d H:i', $start);
$end_datetime = Carbon::createFromFormat('Y/m/d H:i', $end);
$cal = new \Google_Service_Calendar($this->client);
$event = new \Google_Service_Calendar_Event();
$event->setSummary($title);
$start = new \Google_Service_Calendar_EventDateTime();
$start->setDateTime($start_datetime->toAtomString());
$event->setStart($start);
$end = new \Google_Service_Calendar_EventDateTime();
$end->setDateTime($end_datetime->toAtomString());
$event->setEnd($end);
// Create new conference
$conference = new \Google_Service_Calendar_ConferenceData();
$entryPoint = new \Google_Service_Calendar_EntryPoint();
$entryPoint->setAccessCode('wx12z3s');
$entryPoint->setEntryPointType('video');
$entryPoint->setLabel('meet.google.com/wx12z3s');
$entryPoint->setMeetingCode('wx12z3s');
$entryPoint->setPasscode('wx12z3s');
$entryPoint->setPassword('wx12z3s');
$entryPoint->setPin('wx12z3s');
$entryPoint->setUri('https://meet.google.com/wx12z3s');
$conference->setEntryPoints($entryPoint);
$conferenceSolution = new \Google_Service_Calendar_ConferenceSolution();
$conferenceSolution->setIconUri(null);
$conferenceSolution->setKey(new \Google_Service_Calendar_ConferenceSolutionKey());
$conference->setConferenceSolution($conferenceSolution);
$conferenceRequest = new \Google_Service_Calendar_CreateConferenceRequest();
$conferenceRequest->setRequestId($request->_token);
$conferenceSolutionKey = new \Google_Service_Calendar_ConferenceSolutionKey();
$conferenceSolutionKey->setType("hangoutsMeet");
$conferenceRequest->setConferenceSolutionKey($conferenceSolutionKey);
$conferenceRequest->setStatus(new \Google_Service_Calendar_ConferenceRequestStatus());
$conference->setCreateRequest($conferenceRequest);
$event->setConferenceData($conference);
//attendee
if ($request->has('attendee_name')) {
$attendees = [];
$attendee_names = $request->input('attendee_name');
$attendee_emails = $request->input('attendee_email');
foreach ($attendee_names as $index => $attendee_name) {
$attendee_email = $attendee_emails[$index];
if (!empty($attendee_name) && !empty($attendee_email)) {
$attendee = new \Google_Service_Calendar_EventAttendee();
$attendee->setEmail($attendee_email);
$attendee->setDisplayName($attendee_name);
$attendees[] = $attendee;
}
}
$event->attendees = $attendees;
}
$created_event = $cal->events->insert($calendar_id, $event);
$evt->title = $title;
$evt->calendar_id = $calendar_id;
$evt->event_id = $created_event->id;
$evt->datetime_start = $start_datetime->toDateTimeString();
$evt->datetime_end = $end_datetime->toDateTimeString();
$evt->save();
return redirect('/event/create')
->with('message', [
'type' => 'success',
'text' => 'Event was created!'
]);
}
I am using a G suite account so that I can add events and assign hangout meet conferences to it but the problem keeps showing when i try to add newly created event to the user calender

The problem was the access token I am trying to use to access user calendar is wrong. When I deleted all user data and of course his access token saved to the database and tried to login again so that a new record created to the user with a new access token the problem solved and I can now access his calendar and create new events

Related

Struggling to store token for AdSense API

I've successfully managed to connect to the AdSense API and run a report. However, it requires a log in each time I run it, so it won't run as a cron job.
I've found a few other questions related to this. Some advise a service account, while others point out that a service account does not work with AdSense. The proposed solution is to store a token on my server, but I've been struggling to get that to work. Here is my code so far (which works, but requires manual log in):
$scriptUri = "http://".$_SERVER["HTTP_HOST"].$_SERVER['PHP_SELF'];
$client = new Google_Client();
$client->addScope('https://www.googleapis.com/auth/adsense.readonly');
$client->setAccessType('offline');
$client->setApplicationName('My Application name');
$client->setClientId(' MY ID ');
$client->setClientSecret(' MY SECRET ');
$client->setRedirectUri($scriptUri);
$client->setDeveloperKey(' MY KEY '); // API key
$accountId = " MY ACCOUNT " ;
$adClientId = " MY CLIENT " ;
// $service implements the client interface, has to be set before auth call
$service = new Google_Service_AdSense($client);
if (isset($_GET['logout'])) { // logout: destroy token
unset($_SESSION['token']);
die('Logged out.');
}
if (isset($_GET['code'])) { // we received the positive auth callback, get the token and store it in session
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) { // extract token from session and configure client
$token = $_SESSION['token'];
$client->setAccessToken($token);
}
if (!$client->getAccessToken()) { // auth call to google
$authUrl = $client->createAuthUrl();
header("Location: ".$authUrl);
die;
}
$startDate = '2015-11-01';
$endDate = 'today';
$optParams = array(
'metric' => array(
'EARNINGS'),
'dimension' => array('DATE'),
'sort' => '+DATE',
'filter' => array(
'CUSTOM_CHANNEL_NAME==Mega Seating Plan'
)
);
// Run report.
$report = $service->accounts_reports->generate($accountId, $startDate,
$endDate, $optParams);
if (isset($report) && isset($report['rows'])) {
// Get results.
foreach($report['rows'] as $row) {
$date = $row[0] ;
$earnings[$date] = $row[1] ;
}
} else {
print "No rows returned.\n";
}
Can anybody give me any pointers about how I can incorporate token storage into the above code, please?
Thank you to #jkns.co for the previous answer here which helped me to get it working.
Here's my final code:
$scriptUri = "I HAD TO PUT MY ABSOLUTE URL HERE, OTHERWISE THE CRON JOB WOULD LOOK IN THE WRONG PLACE" ;
$client = new Google_Client();
$client->addScope('https://www.googleapis.com/auth/adsense.readonly');
$client->setAccessType('offline');
$client->setApprovalPrompt ("force"); // This line had to be added to force the approval prompt and request a new token
$client->setApplicationName('My Application name');
$client->setClientId('BLAH');
$client->setClientSecret('BLAH');
$client->setRedirectUri($scriptUri);
$client->setDeveloperKey('BLAH'); // API key
$accountId = "BLAH" ;
$adClientId = "BLAH" ;
// $service implements the client interface, has to be set before auth call
$service = new Google_Service_AdSense($client);
if (isset($_GET['logout'])) { // logout: destroy token
unset($_SESSION['token']);
die('Logged out.');
}
if (isset($_GET['code'])) { // we received the positive auth callback, get the token and store it in session
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
// If it successfully authenticates, I request the refresh token
$refreshToken = $client->getRefreshToken();
storeRefreshToken($refreshToken) ; // This function stores the token in MySQL
}
else { // Otherwise it loads the refresh token from MySQL
$refreshToken = getRefreshToken() ;
$client->refreshToken($refreshToken);
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) { // extract token from session and configure client
$token = $_SESSION['token'];
$client->setAccessToken($token);
}
if (!$client->getAccessToken()) { // auth call to google
$authUrl = $client->createAuthUrl();
header("Location: ".$authUrl);
die;
}

Laravel Stormpath not able to access User Object

I am using Laravel and Stormpath for User Management. I am able to register and login user successfully using AJAX.
After successful login only the url is returned to AJAX, but after login when I go to User specific pages I am not able to fetch User Data.
Registration and Login happens in RegisterController
User Pages are rendered using UserController
I've tried to get User data using
$user = app('stormpath.user');
in UserController, but when I do dd($user) null is returned.
How to persist or get User Data after successful login or sign-up in other Controllers?
Any help appreciated! Thanks in advance!
For the Stormpath Laravel integration, when you run AJAX calls, we do not set any cookies. We provide you with the JWT in the header response that you will need to look at and then store them youself. The JWT will then need to be attached to all other requests as a Bearer token which will allow you to use the `$user = app('stormpath.user') method to get the user information out of the JWT.
I finally got everything working. Thank you #bretterer
// Stormpath user account creation
\Stormpath\Client::$apiKeyProperties = "apiKey.id="
.env('STORMPATH_CLIENT_APIKEY_ID').
"\napiKey.secret=".env('STORMPATH_CLIENT_APIKEY_SECRET');
$client = \Stormpath\Client::getInstance();
$apps = $client->tenant->applications;
$apps->search = array('name' => 'My Application');
$application = $apps->getIterator()->current();
$account = \Stormpath\Resource\Account::instantiate(
[
'givenName' => $request->input('username'),
'middleName' => '',
'surname' => 'StromTrooper',
'username' => $request->input('username'),
'email' => $request->input('user_mail'),
'password' => $request->input('user_pass'),
'confirmPassword' => $request->input('user_pass')
]
);
// Create User Account and Log-in the User
try
{
$response = $application->createAccount($account);
$passwordGrant = new \Stormpath\Oauth\PasswordGrantRequest(
$request->input('user_mail'),
$request->input('user_pass')
);
$auth = new \Stormpath\Oauth\PasswordGrantAuthenticator($application);
$result = $auth->authenticate($passwordGrant);
$atoken = cookie("access_token",
$result->getAccessTokenString(),
$result->getExpiresIn()
);
$rtoken = cookie("refresh_token",
$result->getRefreshTokenString(),
$result->getExpiresIn()
);
$response_bag['success'] = url('userprofile');
}
catch (\Stormpath\Resource\ResourceError $re)
{
$response_bag['error'] = $re->getMessage();
$atoken = 'null';
$rtoken = 'null';
}
return response()
->json($response_bag)
->withCookie($atoken)
->withCookie($rtoken);
and in the User controller I am able to access the user details using app('stormpath.user');
and since I was using Laravel 5.1
I had to comment out $token = $request->bearerToken(); from vendor/stormpath/laravel/src/Http/Middleware/Authenticate.php from function public function isAuthenticated(Request $request)

How to attach variable to reset password link view in laravel?

I am using laravel 5.2 where I need to sent an OTP code to reset password, though email is being sent with built in subject and limited message done by make:auth command but how to customize? I have tried to follow the link unfortunately I am unable to understand how i can use this to solve.
I customized the api like this
public function sendResetLinkEmail(Request $request)
{
$this->validateSendResetLinkEmail($request);
$broker = $this->getBroker();
$email = $request->input('email');
$userid = DB::table('users')->where('email','=',$email)->value('id');
$uniqueotp = "DIYA".uniqid();
$curr_timestamp = strtotime(date("Y-m-d H:i:s"));
$date = strtotime("+7 day", $curr_timestamp);
$expiry_otp = date('Y-m-d H:i:s',$date);
$ip_address = $request->ip();
DB::table('otp_users')->insert([
'user_id' => $userid,
'status' => 0,
'otp_code' => $uniqueotp,
'ipaddress'=>$ip_address,
'expires_at'=>$expiry_otp
]);
$response = Password::broker($broker)->sendResetLink(
$this->getSendResetLinkEmailCredentials($request),
$this->resetEmailBuilder()
);
switch ($response) {
case Password::RESET_LINK_SENT:
return $this->getSendResetLinkEmailSuccessResponse($request,$response);
case Password::INVALID_USER:
default:
return $this->getSendResetLinkEmailFailureResponse($response);
}
}
Any idea how I can achieve?
My required email message like this:
Hello, Tamaghna Banerjee Click here to reset your password:
Your OTP is: B16445512121
Reset Your Password through http://localhost/diya/public/password/reset/83baba9f61fc851b9d80b515415ec86c43b03b56b068e1888256db7a7831ba83?email=tamaghnabanerjee%40live.com

Updates records more than one time on laravel

I am trying to update values in laravel. I have a userupdate profile api which I can update the values first time with given parameters and their values but 2nd time when I update same values it gives me user profile does not exist.
My Code is :
public function UpdateUserProfile(Request $request)
{
$id = $request->input('id');
$client_gender = $request->input('client_gender');
$client_age = $request->input('client_age');
$client_weight = $request->input('client_weight');
$client_height = $request->input('client_height');
$client_dob = $request->input('client_dob');
$profile= DB::table('clients')
->where('id',$id)
->update(['client_gender'=>$client_gender,'client_age'=>$client_age,'client_height'=>$client_height,'client_weight'=>$client_weight,'client_dob'=>$client_dob]);
if($profile)
{
$resultArray = ['status' => 'true', 'message' => 'User profile updated Successfully!'];
return Response::json( $resultArray, 200);
}
$resultArray = ['status' => 'false', 'message' => 'User profile does not exist!'];
return Response::json($resultArray, 400);}
first time when I update the value it gives me the response like this:
{
"status": "true",
"message": "User profile updated Successfully!"
}
and when I hit the update request through a postman it gives a 400 Bad request and response is :
{
"status": "false",
"message": "User profile does not exist!"
}
I'd recommend rewriting that function to look like the following; mostly because it reads better and uses the Model methods that are more commonly found in Laravel
public function UpdateUserProfile(Request $request)
{
// this code fails if there is no client with this id
$client = App\Client::findOrFail($request->id);
// attach new values for all of the attributes
$client->client_gender = $request->input('client_gender');
$client->client_age = $request->input('client_age');
$client->client_weight = $request->input('client_weight');
$client->client_height = $request->input('client_height');
$client->client_dob = $request->input('client_dob');
// save
$client->save();
return ['status' => 'true', 'message' => 'User profile updated Successfully!'];
}

laravel login with google account

I am making an application and I want users to login with their google account. I have user oauth-4-laravel and I have this:
UserController.php
// get data from input
$code = Input::get('code');
// get google service
$googleService = Artdarek\OAuth\Facade\OAuth::consumer("Google");
if (!empty($code)) {
// This was a callback request from google, get the token
$token = $googleService->requestAccessToken($code);
// Send a request with it
$result = json_decode($googleService->request('https://www.googleapis.com/oauth2/v1/userinfo'), true);
$user = DB::select('select id from users where email = ?', array($result['email']));
if (empty($user)) {
$data = new User;
$data->Username = $result['name'];
$data->email = $result['email'];
$data->first_name = $result['given_name'];
$data->last_name = $result['family_name'];
$data->save();
}
if (Auth::attempt(array('email' => $result['email']))) {
return Redirect::to('/');
} else {
echo 'error';
}
}
// if not ask for permission first
else {
// get googleService authorization
$url = $googleService->getAuthorizationUri();
// return to facebook login url
return Redirect::to((string) $url);
}
}
After this i get successfully user info and can save user name, in my database. The problem is that after this I want to redirect user to home page and can't do this because with normal login i chec authentication:
if (Auth::attempt(array('email' => Input::get('email'), 'password' => Input::get('password')))) {
return Response::json(["redirect_to" => "/"]);
and with google login i get onlu username , user id and email. How to login directly the user after google login?
If you need to log an existing user instance into your application, you may simply call the login method with the instance:
$user = User::find(1);
Auth::login($user);
This is equivalent to logging in a user via credentials using the attempt method.
For further info see: http://laravel.com/docs/security#manually

Resources