Skip to content

Office.Cloud.Google

apobekiaris edited this page Oct 17, 2020 · 15 revisions

GitHub issues GitHub close issues

About

The Google package authenticates against the Google Cloud services.

Details


Credits: to Brokero that sponsor the initial implementation of this module.


This is a platform agnostic module.

App Service configuration

First off you have to create an Azure application following the next steps:

  1. Go to console.developers.google.com/.
  2. Select Credentials/Create Credentials/OAth client ID
  3. Select Desktop app or Web application.
  4. Select Create and copy the Your Client ID, Your Client Secret to the related XAF model entry.
  5. From the left pane, select Library and enable for the API you want to consume.
  6. Choose the appropriate scopes and copy them into the related model attribute.
  7. The related XAF model is available at: image

Authentication

The module does not replace nor requires the XAF authentication. The module will use the credentials from the application configuration file authenticate/link it self with the Azure application. To authenticate, the end user must execute the Sign in with Google action. If XAF has security installed the action is only active in current user profile, else it is always active. Once there is a valid authentication the Sign in with Google action will be deactivated and the Sing out Google will be activated.

For both platforms once the user authenticated the RefreshToken and AccessToken will be saved with the help of the GoogleAuthentication business object. When the AccessToken expires the module will use the RefreshToken to silently request a new AccessToken. The RefreshToken never expires. If the GoogleAuthentication contains data for the current user and a new AccessToken cannot be acquired, a message will notify the end user to navigate to his/her profile for authentication.

Query the Google People api

In the screencast on the examples section, we executed the Show Google Account Info action to display a popup view with all the details of the connected Google account. Below is all the module code used for it:

internal static class ShowGoogleAccountInfoService{
	//action declaration refer to the Reactive module wiki
	public static SimpleAction ShowGoogleAccountInfo(this (AgnosticModule, Frame frame) tuple) 
		=> tuple.frame.Action(nameof(ShowGoogleAccountInfo)).As<SimpleAction>();

	public static IObservable<Unit> ShowGoogleAccountInfo(this ApplicationModulesManager manager){
		//export the google EmailAddress so we can display a XAF view for it
		manager.Modules.OfType<AgnosticModule>().First().AdditionalExportedTypes.Add(typeof(EmailAddress));
		var registerViewSimpleAction = manager.RegisterViewSimpleAction(nameof(ShowGoogleAccountInfo)).ActivateInUserDetails().Publish().RefCount(); 
		return manager.WhenApplication(application 
				//when the action executed show the Info View
				=> registerViewSimpleAction.WhenExecute().ShowAccountInfoView().ToUnit())
			//register the action for the design time Model Editor
			.Merge(registerViewSimpleAction.ToUnit());
	}

	private static IObservable<Person> ShowAccountInfoView(this IObservable<SimpleActionExecuteEventArgs> source) 
		=> source.SelectMany(e => {
				e.ShowViewParameters.CreatedView = e.Action.Application.NewView(ViewType.DetailView, typeof(EmailAddress));
				e.ShowViewParameters.TargetWindow = TargetWindow.NewWindow;
				return e.Action.Application.GoogleUser().ObserveOn(SynchronizationContext.Current)
					.Do(user => e.ShowViewParameters.CreatedView.CurrentObject = user.EmailAddresses.First());
			});

	private static IObservable<Person> GoogleUser(this XafApplication application) 
	//authorize and then create the PeopleService to retrieve the auth google Person
		=> application.AuthorizeGoogle().NewService<PeopleService>()
			.SelectMany(service => {
				var request = service.People.Get("people/me");
				request.RequestMaskIncludeField = "person.emailAddresses";
				return request.ExecuteAsync(); //
			});

Prerequisites

In order to execute the asynchronous operations:

  1. The Async attribute the Default.aspx must be true.

    <%@ Page Language="C#" AutoEventWireup="true" Inherits="Default" EnableViewState="false"
     ValidateRequest="false" CodeBehind="Default.aspx.cs" Async="true" %>
  2. The AspNetSynchronizationContext context should be used by setting the targetFramework to a value greater than 4.5.1 in the web.config.

    <system.web>
     <httpRuntime targetFramework="4.5.1"/>

Possible future improvements:

  1. Authenticate against XAF.
  2. Any other need you may have.

Let me know if you want me to implement them for you.


Examples

In the screencast below we see authentication against Google/People/Me service. To demo auth token database persistence we logOff and the clean the browser cookies. At the bottom the Reactive.Logger.Client.Win is reporting as the module is used. This demo is Easytested with this script for the last three XAF major versions, compliments of the Xpand.VersionConverter

Xpand XAF Modules Office Cloud Google

image

Installation

  1. First you need the nuget package so issue this command to the VS Nuget package console

    Install-Package Xpand.XAF.Modules.Office.Cloud.Google.

    The above only references the dependencies and nexts steps are mandatory.

  2. Ways to Register a Module or simply add the next call to your module constructor

    RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.Office.Cloud.GoogleModule));

Versioning

The module is not bound to DevExpress versioning, which means you can use the latest version with your old DevExpress projects Read more.

The module follows the Nuget Version Basics.

Dependencies

.NetFramework: net461

DevExpress.Persistent.Base Any
Fasterflect.Xpand 2.0.7
Google.Apis.Auth 1.49.0
JetBrains.Annotations 2020.1.0
Newtonsoft.Json 12.0.3
System.Reactive 4.4.1
System.ValueTuple 4.5.0
Xpand.Extensions 2.202.57
Xpand.Extensions.Office.Cloud 2.202.58
Xpand.Extensions.Reactive 2.202.58
Xpand.Extensions.XAF 2.202.58
Xpand.Extensions.XAF.Xpo 2.202.54
Xpand.XAF.Modules.Reactive 2.202.58
Xpand.VersionConverter 2.202.10

Issues-Debugging-Troubleshooting

To Step in the source code you need to enable Source Server support in your Visual Studio/Tools/Options/Debugging/Enable Source Server Support. See also How to boost your DevExpress Debugging Experience.

If the package is installed in a way that you do not have access to uninstall it, then you can unload it with the next call at the constructor of your module.

Xpand.XAF.Modules.Reactive.ReactiveModuleBase.Unload(typeof(Xpand.XAF.Modules.Office.Cloud.Google.Office.Office.Cloud.GoogleModule))

Tests

The module is tested on Azure for each build with these tests. All Tests run as per our Compatibility Matrix