OAuth2 Token Source for DWD (Domain Wide Delegation) on Google App Engine Standard Environment
An example, using DWD & impersonation on the default App Engine Service Account:
package main
import (
"html/template"
"net/http"
"context"
"golang.org/x/oauth2"
"google.golang.org/api/admin/directory/v1"
"github.com/iamacarpet/go-gae-dwd-tokensource"
"private/model/user"
)
type AuthCheckMiddleware struct {
User *user.User
UserThumbURL string
LogoutURL string
}
func (c *AuthCheckMiddleware) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
ctx := r.Context()
if u := user.Current(r); u == nil {
// If no user logged in, redirect to login.
url, _ := user.LoginURL(ctx, r.URL.Path)
http.Redirect(rw, r, url, 302)
return
} else if ! c.isUserAllowed(ctx, u.Email) {
log.Errorf(ctx, "Access Denied for email %s to %s", u.Email, r.URL.Path)
// Example of rendering a 403 page.
errorTemplate := template.Must(template.ParseFiles("views/403.html"))
c.User = u
c.UserThumbURL, _ = user.GetAnonymousUserThumbnail(ctx, u.Email)
c.LogoutURL, _ = user.LogoutURL(ctx, r.URL.Path)
rw.WriteHeader(403)
errorTemplate.Execute(rw, c)
return
}
next(rw, r)
}
func (c *AuthCheckMiddleware) isUserAllowed(ctx context.Context, email string) bool {
return c.groupMembershipCheck(ctx, "[email protected]", email)
}
func (c *AuthCheckMiddleware) groupMembershipCheck(ctx context.Context, group string, email string) bool {
transport := &oauth2.Transport{
Source: dwdtoken.AppEngineDWDTokenSource(ctx, "[email protected]", admin.AdminDirectoryUserReadonlyScope, admin.AdminDirectoryGroupMemberReadonlyScope),
}
client := &http.Client{Transport: transport}
srv, err := admin.New(client)
if err != nil {
log.Errorf(ctx, "AuthCheckMiddleware.groupMembershipCheck: API Init: %s", err)
return false
}
result, err := srv.Members.HasMember(group, email).Do()
if err != nil {
log.Errorf(ctx, "AuthCheckMiddleware.groupMembershipCheck: API Membership Check (%s of %s): %s", email, group, err)
return false
}
return result.IsMember
}
To make this work, you need to edit the default service account and tick "Enable DWD", then follow this guide to add it to your G Suite domain.