I have been working on google_calendar module, trying to get it usable, and as part of that I created another module, google_secrets, which currently does two things:

- implements a service factory for Google_Client objects
- implements a new plugin type for storing the Google Secrets file, a JSON file that you download to get machine access to the API (as opposed to oAuth based access).

Machine access is needed when (as in my case) there is no direct user involvement, e.g. showing events from one or more company calendars. Google calls this a "service account". With an oAuth account the assumption is that the owning user is always available to re-authenticate.

The new plugin type is needed (IMO) because the JSON file contains quite sensitive information but it is not clear that any one way of storing it is suitable for all cases. I have implemented two versions of it: storing a file somewhere in the filesystem (static file) and storing in the drupal private file system (managed file). Other implementations could include storage in a key-value database.

I think it would be to both projects benefit to merge google_secrets into google_api_client, so as to leave just one project to maintain. If you are amenable, can we talk about the best way to get this done?

My project code is at https://git.drupalcode.org/project/google_secrets/ 8.x-1.x
- https://www.drupal.org/project/google_secrets/
The current pre-alpha state of google_calendar module is https://git.drupalcode.org/project/google_calendar/ 8.x-2.x
- https://www.drupal.org/project/google_calendar/

Comments

rivimey created an issue. See original summary.

dakku’s picture

@rivimey: firstly thank you for sharing your fantastic. I think it would be great to merge your project with google_api_client. It will be easier for site builders and developers to install and install 1 module.

Some high level thoughts on integration:

  • I think we could abstract the logic to store and retrieve secrets into its own service.
  • google_api_client can call it along with any other implementation that needs to access the secrets.
  • we currently manage the creds in Config (YML) this allows the site admins / devops to switch this out using something like config split and provide specific YML for each environment.
  • I had considered the idea of managing the file in a file system and decided against it - the deployment is made complicated

Please feel free to share your thoughts on what direction you think we could take.

rivimey’s picture

@dakku

  • I agree a service would be a good choice - a previous implementation did just that and it's only different now because I wasn't sure of the overall way forward.
  • I wondered about storing the detail in yml files as well, but it does enforce a particular implementation, and having got my head around plugins, it is I believe better with plugins and not particularly complex.
  • Having a file means the user can use the $client->setAuthConfig() on that file without issue; other service account options are more complex for the client. See https://cloud.google.com/docs/authentication/getting-started
  • Keeping a plugin for the storage of client secrets means there is a need to decide which implementation is being used, which for the moment I have put in yml config, but perhaps should be in settings.php for safety.
  • The existing GoogleApiClient class needs to be adapted to permit both oAuth and service account access - mostly getClient() but some other places.

A medium term goal for google_calendar is to support more than one active account (currently more than one calendar, but all for the same account). This requires maintaining more than one authorization key.

A long term goal for google_calendar is to permit both service account access (as now) and oAuth access. The latter requires the oAuth capabilities of your module, additional config and UI elements, and additional logic around refresh and update, and more.

It therefore seems plausible to me that a site could want both several service accounts and several oAuth accounts usable at the same time. I'm not sure how best to do this.

So, an overall feature set:

  • Service to return a Google_Client object, either unauthenticated, or authenticated by either oAuth or service account credentials
  • Service to return a default authentication method (oAuth or service account), with options:
    • a method per module requesting (google_calendar / google cloud / ... )
    • by yml configuration somehow
  • ??other 'glue' code needed for clients to effectively use, e.g. a field definition that can be attached to entities?
  • UI / form code to select default method(s) and desired storage
  • UI / form code to report status (e.g. via site status report) : include which accounts are configured, etc
  • drush commands to verify account access, refresh tokens, report status, ...
  • more?
rivimey’s picture

Bump?
Is what I put in #3 useful, or perhaps not what you meant?

dakku’s picture

@rivimey sorry I got occupied with a client project :D
Let me digest through the proposal above and share some thoughts soon.

rivimey’s picture

@dakku, thanks. I've just pushed further updates to google_secrets which somewhat firms up my view/needs of it.

rivimey’s picture

@dakku, hope your project is going well. Thought I would update you on my progress: the google_secrets module is now alpha3 and getting reasonably stable now. Beta is in sight. I have google_calendar working well now and have issued alpha1; alpha2 is close and probably beta is in sight though tests are needed.

I would like to discuss with you how the modules could be merged - it makes no sense to have two! How do you feel about the approach I have taken?

dakku’s picture

@rivimey - thanks again for your work :D

I did a quick scan through the module you linked and wanted to discuss a few approaches:

- secrets plugin with managed and unmanaged files: it feels we could do this with config management? With config management, we can use config split and switch the config to be environment specific. Additionally, sensitive yamls can be managed in a separate config repo. Maybe I am not understanding the usecases behind whereby this is required!

- Using the plugin approach, how are the deployments managed for multiple environments?

- If the requirement is to have multiple secrets, we can accommodate directly via this module.

look forward to your thoughts..

sadashiv’s picture

Hi Janak and Ruth,

I think it's three of us making similar modules and we need to merge.

I have Gauth and Gcal

I am closing Gcal anyways, because I see that Google Calendar already has things developed which I was planning. Let's merge our projects and make it work.

Thanks,
Sadashiv

rivimey’s picture

@sadashiv, I agree we should only have one google auth project, and @dakku is I believe in general agreement too, and I am happy to merge google_secrets into google_api_client (i.e. killing off google_secrets). Equally I am happy to merge into GAuth if that is best; basically, whatever works and preferably just one of it!

However, the main reason google_secrets exists is as a wrapper to store the sensitive API access information, as well as the more obvious need for a way to create a Client from a service. I would argue that storing this sort of info in a code repo is not secure: too many "private" keys are now public by that route. I wanted to do something that would work even for multi-headed sites without shared filesystems, or by using redis or memcache, or a SQL table, or anything else. The code's main flaw is that at present it must return a filename, not the data in the file: this is a G-API legacy and would ideally be worked around.

The point of the plugins is extensibility: I have provided two which made sense to me: a static file "somewhere" visible to php, and a Drupal-managed private file. Deployment could be as simple as sticking the file in the code repo (insecure but handy), copying it around in the same way as the site's other private files, or putting it in a database with an as-yet-unbuilt plugin that extracted it on the fly.

I am not sufficiently aware of the capabilities of split config, etc, to know if that would solve the problems securely, so I rolled my own.

Moving on:

Given we are where we are, I think the best option for google_calendar users is to get to a point where google_secrets is for a while a wrapper for , so a new release can update google_secrets to do that, and also "require" whatever other module/library is needed to do the job. At some later point a new version can then eliminate the wrapper.

As for the nature of :

- A goal for google_calendar is to support multiple active authentications at a time - eg. to enable calendars from multiple service accounts.

- A long-term goal for google_calendar is to support OAuth2 security, in some far-off world that google_calendar can directly manipulate user calendars (rather than just service calendars). Dealing with OAuth2 is what made me aware of google_api_client in the first place.

- Obviously there are non-calendar uses of the API, and those should be supported. Q: should we have Drupal 'services' for each of the GAPI services? Part of me says "yes" (witness google_secrets being able to create a Google Client Calendar object) but part says "that's a lot of services".

- I am also aware that the smtp module has a sword of Damocles over it, because Google wants people to use OAuth2 to login to send mail to its mail servers. There is a sandbox version of the module that works that way but nobody has yet stepped in to agree changes and merge a patch to get it official. It would make some sense, perhaps, to try to get in there, too?

When I looked at google_api_client code before (and it was a while), there is quite a difference in structure. I think the first step in any merge would be to come up with a common structure of the result which would satisfy all users, then figure out how to get there from here. I don't think I can help without that first step.

So, I suggest that the needed thing is a "workshop" on the topic. Would @sadashiv and @dakku be up for that? Can I suggest inviting @TrevorBradley to the mix, as the guy who did the smtp sandbox? Is there anyone else who has an interest?

As an afterthought, One of the things I did in google_calendar was a wizard to guide users through the complex steps needed to make a service account. A lot of it would be the same for a non-calendar user. Should that wizard be moved into a future google_api_client module?

sadashiv’s picture

@rivimey correct me if I made any mistake in understanding, What I understood is basically you are uploading the json file with all creds and you mean that it's easy for multisite users to access secret key files of other users as they are easily accessible from filesystem. Here you mention putting those in a SQL table, this is what I did in GAuth. I store everything in db and the site config only accessible to admins i.e. "administer site configuration".

Further I see that you want multiple account authentications and this is supported in GAuth. I am currently working on GAuth User module (this already exist in the drupal 7 branch) I am making it for drupal 8 so that we can have end user authenticate his/her google services and site can perform operations on user data.

If we want a workshop/discussion call we can have one, I'll be happy to demo GAuth (though drupal 8 lacks all features) but I have plans for developing them and see that it's better than the drupal 7 version. I am sure @dakku and I can collaborate and improve the module.

Please provide link to the smtp project, I'll inform him or you can update him to rely on our module for authentication. If possible check GAuth out and update me if you see improvements, I am sure GAuth User once released will serve all purposes of google calendar and other projects.

Thanks,
Sadashiv.

rivimey’s picture

@sadashiv, the secrets module provides an extensible (via plugin) way to store and access the credentials information required to use a google service account. Currently the plugins in use enable that by storing the file and enabling it to be read.

I have had a look at GAuth and I can see a lot of work done, though (forgive my ignorance) it looks like it is geared to OAuth accounts. Service accounts have differences, in particular there is no linkage to any Drupal user account and there are no callbacks.

Do you think GAuth can be extended to support service accounts? I think if that is so I am amenable to switch to GAuth.

I do think a group conversation would help.... would it be best to use doodle.com to figure out a time to do that? The reason for a chat would simply be to agree the structure of the way forward.

SMTP is at drupalorg/project/smtp and the issue was:

TrevorBradley's comment

sadashiv’s picture

Hi @rivimey,

We are shutting down GAuth, I and @dakku decided this that we will carry forward google_api_client. Currently we are discussing on 8.x-2.x for google_api_client where we have all features of GAuth in Google Api Client module and may be migrations for drupal 7 and upgrade for 8.x-1.x.

You are right GAuth is tied up with OAuth and doesn't hadle service account, I think it's time that I discuss with @dakku about this and then can decide whether to include service account support in 8.x-2.x or we need to postpone.

In theory it should be easy like instead of saving the client details as separate fields as I do in GAuth save json in single field and use the setAuthConfig, but I am thinking like should I create a separate entity for Service accounts as it's different in nature like it's just storage and one wrapper where we provide the GoogleClient object from the stored info as there is no need of authentication, so I need to discuss this with @dakku and get his views on this.

One thing for sure, I will extend the support of Google Api Client for Service account and it will be soon, so you can think of depending on Google Api Client for that.

For the smtp integration, I want to provide them integrate with Google Api Client but I think our module still needs improvements.

Thanks,
Sadashiv.

rivimey’s picture

Are you talking about this in another Issue that I can see and join in with?

One thing I feel is very necessary for google_calendar is that there is a proper and preferably automated migration in place. I hope that can be arranged?

sadashiv’s picture

I updated the SMTP issue so that someone developing can give this a try, I am interested in that case but after release 8.x-2.x because that's a major rewrite of the module, I already pushed the basic working code to git today, now I am working on upgrade from 8.x-1.x which I think I pushed some code but want to test it etc. Also want to discuss the drupal service implementation with @dakku as this is a major rewrite. I want to make migration for drupal 7. Once we have all these in place and have some release for 8.x-2.x I'll start working on 8.x-3.x where I plan to include what you are asking i.e. services account.

Now for the google_calendar, I think we can make migrations where you can also contribute/help with the current google secrets structure ( have not managed to study eveything so that we can basically read from the files and import them in db.

Thanks,
Sadashiv.

rivimey’s picture

The primary link for google_secrets / google_calendar is a named service which returns an authorised and instantiated Google_Service_Calendar structure. At present this service throws exceptions if something fails, which was not my desire but is as it is.

sadashiv’s picture

Version: 8.x-1.x-dev » 8.x-3.x-dev
Status: Active » Needs review

Hi @rivimey,

I have one basic version for Service account support. Please check 8.x-3.x-dev

What this branch has
1) New configuration entity as explained at https://www.drupal.org/node/1809494 for entering Google Service accounts.
2) Config Entity "Google Api Services Client" created by above form
3) Has fields as id, machine_name, auth_config which is json field as we had for 8.x-1.x, Services which are authenticed for the key and specific scope selection.
4) Service for getting a google api client build for services account similar to what we have for ouath in 8.x-2.x

What's pending:
1) Migrations for google_secrets: I can do this once we say that the module developed so far is all good. I may need some help in migration as have not studied google_secrets in detail yet, I plan to do that soon.

Thanks,
Sadashiv.

sadashiv’s picture

Hi @rivimey,

Please check latest branch, so that we can push this.

Thanks,
Sadashiv.

rivimey’s picture

Hi, I've had a look at 3.x now. Been very busy working on being a magazine editor and keeping the garden from invading!

I can see from the branch release notes in the how loading a configured credential, but there is little on how to configure and create the persistent credentials from which that is done.

I presume that you have dropped google_secrets idea of a plugin, and rely on config entities rather than the raw json file.

What I can't see is what I would replace the old plugin code with in google_calendar's settings or my wizard form? I created the wizard because getting a client and registering it was decidedly not simple, and it took me several hours to decode what was needed and that what I had done was the thing I was expected to do.

I can see some things in google_api_client's settings form about client credentials; is this what I am looking for, as it seems to suppose there is only one credential for the whole site?

sadashiv’s picture

How to configure:
1) Goto the configuration page i.e. admin/config/services/google_api_service_client
2) Click on "Add Google Api Service Account" button
3) On the form you need to name the credential, copy the json content in the credentials field, select services and scopes for which the json file is authorized and save
4) Here we have successfully saved the json in configuration and we can retrieve it using config/Service provided by the module.

I checked the google calendar code i.e. https://git.drupalcode.org/project/google_calendar/-/tree/8.x-2.x/src/Wi.... and what I understand is in Wizard6 you are creating a new google_secrets_store i.e. saving the json using google_secrets_store_manager. I think we need to change this now to save a Google Api Service Account. Here we will be using the core EntityTypeManager and create a new instance and save.

We then need to make a minor change in the saveData function to save the id of the Google Api Service account (machine Name) instead of saving "client_secret_config" in the config.

Now wherever you need the Google_Client option retrieve the machineName from the config and use the code

$google_api_service_client = \Drupal::entityTypeManager()->getStorage('google_api_service_client')->load('SERVICE_ACCOUNT_ID'); // SERVICE_ACCOUNT_ID will be from the config which was saved by the wizard form.
// Get the service.
$googleService = \Drupal::service('google_api_service_client.client');
// Set the account.
$googleService->setGoogleApiClient($google_api_service_client);
// Get objects
$serviceClasses = $googleService->getServiceObjects();
// Now you can use $serviceClasses['calendar'] object, it is object of Google_Service_Calendar

Overall I think you can configure the Wizard later and for now configure the service account manually and save the machine name in some config variable, and try the google client working first, once you see that's working the you can change the wizard to create google api service account.
Update me if you have any other queries.

Hth,
Sadashiv.

sadashiv’s picture

Hi @rivimey,

Do you need any help or have any queries, just want to update that added documentation for the module at https://www.drupal.org/docs/contributed-modules/google-api-php-client. You can refer some part. I think I can also contribute some part of the code in google calendar, add me as a co maintainer and I can code some part of the integration may be as a separate branch or something as a PR approach on github so that you can review before pushing it.

Thanks,
Sadashiv.

rivimey’s picture

Hi, I have been dipping in and out of trying to get ahead of the other things I'm doing.

I have had some problems with the module because it crashes on my default-for-composer Drupal 8.9 config. I am using a /web/ directory configuration, and using composer to include the Google api rather than the libraries module. The code in _google_api_client_read_scope_info() assumes I think that the 'vendor' directory is within the webroot, but for the default composer config it is not.

I wrote this to try to return the correct google client library directory in my attempt to work out the location of the google api module:

function google_api_client_load_library($return_path = FALSE) {
  if (class_exists('Google_Client')) {
    // Composer install so no problem with lib.
    if ($return_path) {
      $reflect = new ReflectionClass('Google_Client');
      $client_php = $reflect->getFileName();
      // TODO: This fails on Windows (dir sep).
      $strip = "/src/Google/Client.php";
      $dir = '';
      if (strpos($client_php, $strip) !== FALSE) {
        $dir = str_replace($strip, '', $client_php);
      }
      return $dir;
    }
    return TRUE;
  }

  $library = \Drupal::service('library.discovery')
    ->getLibraryByName('google_api_client', 'google-api-php-client');
  if ($library) {
    $php_files = array_keys($library['php']);
    $library_exists = file_exists($php_files[0]);
    if ($library_exists) {
      require_once $php_files[0];
      if ($return_path) {
        return 'libraries/google-api-php-client/';
      }
      return TRUE;
    }
  }
  return FALSE;
}

but that still leaves the first lines of _google_api_client_read_scope_info(). I have amended it as follows but it's a horrible hack:

function _google_api_client_read_scope_info() {
  $path = google_api_client_load_library(TRUE);

  // TODO: Hack: the services are in a directory parallel to the client, with "-services" appended... so this kinda works!
  $path .= '-services/src/Google/Service/';

  $files = scandir($path);

The standard version is broken because even if $path is set correctly by the google_api_client_load_library() call, it won't have a 'vendor' subdirectory -- it is itself a grandchild of the vendor directory. I would expect this code could use ReflectionClass::getFileName() for the class Google_Service to identify the location of the services module, and thus the likely location of the other services classes. This would avoid the need to assume a vendor directory layout (which IMO is necessary).

However this all feels wrong... Is there no API in the Google Services to say 'enumerate available/enabled sub APIs'? I would hope that such a function would avoid the need for any scandir() or reflecting classnames, and for the $names array as well. Then a "class_exists" call determines if it's already loaded or if a library load is needed.

rivimey’s picture

Further thoughts, now I have worked through the crash.

- DX: I have found the class name GoogleApiServiceClientService somewhat confusing, Might it be possible to rename it?

- DX: I would like to be able to interact with the Google_Client class before it is used for authentication, e.g. to set the application name and/or the guzzle client options. This doesn't seem to be possible.

- DX: The Google**Interface classes should be in the same part of the namespace as the main class (i.e. ...\Entity)

- UX: In the client UI I can enter the various settings (client id, client secret, etc) for the config item, but trying to authenticate fails, with a message that suggests it's trying to do it as a personal account, not a service account.

- UX: Is there a place where I can upload the google auth json file to define the auth parameters, rather than opening the file and pasting in? I didn't find it if so.

rivimey’s picture

I have now pushed a branch 'drupal9' to the google_calendar project's git which has the current state of things. Basically it's working, but the config wizard has not been modified, and neither has the command line tools. Docs work is needed too.

I have tried to include an update hook to import previous config into a new config entity, but its not tested and probably broken :( ... would appreciate feedback.

Getting to releasable state (i.e. not in a feature branch) requires:
- finishing wizard, command line, docs on my part;
- addressing the issues noted above with composer built sites (basically, make use of libraries module optional);
- ... and probably some tweaks and adjustments not yet noticed.

sadashiv’s picture

Hi @rivimey,

Thanks for providing inputs, currently I am busy with one project with a organization, but surely address issues you mentioned.

Few replies to #23

-I use GoogleApiClient for OAuth accounts and GoogleApiServiceClient for Service accounts which is why I kept the naming accordingly, I prefer to keep it the same so that 20+ developers trying it don't get error in the next upgrade.

-It is possible to work with the Google_Client object eg

$google_api_service_client = \Drupal::entityTypeManager()->getStorage('google_api_service_client')->load('SERVICE_ACCOUNT_ID'); // SERVICE_ACCOUNT_ID will be from the config which was saved by the wizard form.
// Get the service.
$googleService = \Drupal::service('google_api_service_client.client');
// Set the account.
$googleService->setGoogleApiClient($google_api_service_client);
$googleService->googleClient->setApplicationName('Google Calendar'); // This will work.

-Do you mean that the service class like Google_Service_Calendar should be at \Google_Service_Calendar or do you mean some other classes, can you give some example?

-We don't use OAuth client but use the service account only, so basically there are two ways provided by the module and we stick to Service account for google calendars and not use the OAuth Client

-I'll think about it as a improvement in future version, currently I have only the copy paste method.

For #24
I'll check and improve the library detection logic if it is done in different folder than vendor or something as you mentioned in #22

Thanks,
Sadashiv

rivimey’s picture

-I use GoogleApiClient for OAuth accounts and GoogleApiServiceClient for Service accounts which is why I kept the naming accordingly, I prefer to keep it the same so that 20+ developers trying it don't get error in the next upgrade.

I was referring specifically to "GoogleApiServiceClientService" -- I don't understand the reason for/meaning of the second word "Service".

The upgrade path if you did change it was to declare a class alias, so the existing name is an alias for whatever new name was used.

-It is possible to work with the Google_Client object eg:

But you cannot access it before the authentication has happened (as part of setGoogleApiClient), so if you want to set the application name, or configure guzzle differently from standard (as I do), you're stuck, and it is too late to do that afterwards, because if you needed it at all, you need it for the first call.

I wondered if the way to make this happen is to supply a Google_Client object as a second argument to setGoogleApiClient() that will be used instead of the one created within that function, which would be pretty simple to do as a default argument.

-Do you mean that the service class like Google_Service_Calendar should be at \Google_Service_Calendar or do you mean some other classes, can you give some example?

No. I was referring to GoogleApiClientInterface being in the same namespace as GoogleApiClient, GoogleApiServiceClientInterface being in the same namespace as GoogleApiServiceClient, that is, in the \Drupal\google_api_client\Entity namespace.

-We don't use OAuth client but use the service account only, so basically there are two ways provided by the module and we stick to Service account for google calendars and not use the OAuth Client

That was partly my fault - I didn't find the form to add a service account entity and only discovered adding the normal oauth entity. Perhaps some additional top-of-form "blue-button" links would make it clearer (as I have done with the google_calendar forms).

-I'll think about it as a improvement in future version, currently I have only the copy paste method.

That's fine - not a big deal for programmers, but much better for site builders.

For #24 I'll check and improve the library detection logic if it is done in different folder than vendor or something as you mentioned in #22

Thanks. For me, being able to use the module with the google/apiclient code being pulled in by composer into vendor is critical.

This is a sample of the directory tree created by the recommended drupal composer project

root/composer.json
root/composer.lock
root/config
root/config/sync
root/vendor
root/vendor/autoload.php
root/vendor/google
root/vendor/google/apiclient
root/vendor/google/apiclient/src
root/vendor/google/apiclient/src/Client.php
root/vendor/google/apiclient-services
root/vendor/google/apiclient-services/src
root/web/
root/web/index.php
root/web/core
root/web/modules
root/web/modules/contrib
root/web/modules/contrib/google_api_client
root/web/modules/contrib/google_api_client/src
root/web/modules/contrib/google_api_client/google_api_client.info.yml
root/web/libraries
root/web/themes
...

  • sadashiv committed 376b44a on 8.x-3.x
    Adding option to allow developers to set Google client as requested in #...
sadashiv’s picture

I was referring specifically to "GoogleApiServiceClientService" -- I don't understand the reason for/meaning of the second word "Service".

The upgrade path if you did change it was to declare a class alias, so the existing name is an alias for whatever new name was used.

The first Service is for Service Account type and the second Service is for the class is offfers a Service

But you cannot access it before the authentication has happened (as part of setGoogleApiClient), so if you want to set the application name, or configure guzzle differently from standard (as I do), you're stuck, and it is too late to do that afterwards, because if you needed it at all, you need it for the first call.

I wondered if the way to make this happen is to supply a Google_Client object as a second argument to setGoogleApiClient() that will be used instead of the one created within that function, which would be pretty simple to do as a default argument.

Committed at https://www.drupal.org/commitlog/commit/98555/376b44abec7c553cdb949bdfc8...

No. I was referring to GoogleApiClientInterface being in the same namespace as GoogleApiClient, GoogleApiServiceClientInterface being in the same namespace as GoogleApiServiceClient, that is, in the \Drupal\google_api_client\Entity namespace.

I referred to few core modules like user (https://git.drupalcode.org/project/drupal/-/tree/9.0.x/core/modules/user...), media, etc and they all keep it out of Entity so I just kept it out of Entity.

Working on composer install, going to try composer install drupal.

Thanks,
Sadashiv.

sadashiv’s picture

Hi @rivimey,

I fixed issue with drupal installed using composer, it's released in the new version, you can try that. I checked previously and didn't find any api function which tells me which apis are supported by the installed google api client so I made my own function. I think it works now so thanks for identifying this issue.

Thanks,
Sadashiv.

sadashiv’s picture

Hi @rivimey,

Long time no see, Do you need my help in converting/coding for Google Calendar or are you having issues with code or something else?

Thanks,
Sadashiv.

rivimey’s picture

Sorry, multiple things on the go at once, not least one of my main servers' PSU died dramatically and took the MB and CPU with it :(

I would definitely appreciate input if you can try what's there out, but perhaps leave it a day and I will try to schedule time tomorrow to integrate the changes you made. Thanks for the reminder by the way.

sadashiv’s picture

Same here, My main working machine Mac book is not charging and not working on plug in power, I tried my desktop and it burnt something in PSU and don't know what it took along with the PSU, Now managed to repair my 6 years old laptop which is low on memory and can't have everything (browser and phpstorm) running together, so currently working with one of the apps shut.

May be will checkin this weekend.

Thanks,
Sadashiv.

sadashiv’s picture

Hi @rivimey,

Was busy with few other projects, but today have cloned google calendar 2.x and have started working on my local. I created a separate issue on google calendar module at https://www.drupal.org/project/google_calendar/issues/3161318 and will provide a patch there,

I am going to most parts which I understand and provide a patch with basic working wizard and other depending fixes, will update that case when I have something.

Thanks,
Sadashiv.