3
0

Added oauth2 outbound auth handler

This commit is contained in:
Peter Grlica 2021-09-01 14:11:59 +02:00
parent 4d5ed1da26
commit 828a044a67
4 changed files with 288 additions and 0 deletions

View File

@ -0,0 +1,170 @@
package automation
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// automation/automation/oauth2_handler.yaml
import (
"context"
atypes "github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/pkg/wfexec"
)
var _ wfexec.ExecResponse
type (
oauth2HandlerRegistry interface {
AddFunctions(ff ...*atypes.Function)
Type(ref string) expr.Type
}
)
func (h oauth2Handler) register() {
h.reg.AddFunctions(
h.Authenticate(),
)
}
type (
oauth2AuthenticateArgs struct {
hasClient bool
Client string
hasSecret bool
Secret string
hasScope bool
Scope string
hasTokenUrl bool
TokenUrl string
}
oauth2AuthenticateResults struct {
AccessToken string
RefreshToken string
Token interface{}
}
)
// Authenticate function Authentication: OAUTH2
//
// expects implementation of authenticate function:
// func (h oauth2Handler) authenticate(ctx context.Context, args *oauth2AuthenticateArgs) (results *oauth2AuthenticateResults, err error) {
// return
// }
func (h oauth2Handler) Authenticate() *atypes.Function {
return &atypes.Function{
Ref: "oauth2Authenticate",
Kind: "function",
Labels: map[string]string(nil),
Meta: &atypes.FunctionMeta{
Short: "Authentication: OAUTH2",
},
Parameters: []*atypes.Param{
{
Name: "client",
Types: []string{"String"}, Required: true,
},
{
Name: "secret",
Types: []string{"String"}, Required: true,
},
{
Name: "scope",
Types: []string{"String"}, Required: true,
},
{
Name: "tokenUrl",
Types: []string{"String"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "accessToken",
Types: []string{"String"},
},
{
Name: "refreshToken",
Types: []string{"String"},
},
{
Name: "token",
Types: []string{"Any"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &oauth2AuthenticateArgs{
hasClient: in.Has("client"),
hasSecret: in.Has("secret"),
hasScope: in.Has("scope"),
hasTokenUrl: in.Has("tokenUrl"),
}
)
if err = in.Decode(args); err != nil {
return
}
var results *oauth2AuthenticateResults
if results, err = h.authenticate(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.AccessToken (string) to String
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("String").Cast(results.AccessToken); err != nil {
return
} else if err = expr.Assign(out, "accessToken", tval); err != nil {
return
}
}
{
// converting results.RefreshToken (string) to String
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("String").Cast(results.RefreshToken); err != nil {
return
} else if err = expr.Assign(out, "refreshToken", tval); err != nil {
return
}
}
{
// converting results.Token (interface{}) to Any
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Any").Cast(results.Token); err != nil {
return
} else if err = expr.Assign(out, "token", tval); err != nil {
return
}
}
return
},
}
}

View File

@ -0,0 +1,88 @@
package automation
import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"github.com/cortezaproject/corteza-server/pkg/http/auth"
"golang.org/x/oauth2"
)
type (
secureStoragerTodo struct{}
oauth2Handler struct {
reg oauth2HandlerRegistry
}
)
func Oauth2Handler(reg oauth2HandlerRegistry) *oauth2Handler {
h := &oauth2Handler{
reg: reg,
}
h.register()
return h
}
func (h oauth2Handler) authenticate(ctx context.Context, args *oauth2AuthenticateArgs) (res *oauth2AuthenticateResults, err error) {
var (
u *url.URL
token *oauth2.Token
)
if !args.hasClient {
err = fmt.Errorf("could not init auth, client key missing")
return
}
if !args.hasSecret {
err = fmt.Errorf("could not init auth, secret key missing")
return
}
if !args.hasScope {
err = fmt.Errorf("could not init auth, scope missing")
return
}
if !args.hasTokenUrl {
err = fmt.Errorf("could not init auth, token url missing")
return
}
if u, err = url.Parse(args.TokenUrl); err != nil {
err = fmt.Errorf("could not init auth, token url invalid: %s", err)
return
}
params := auth.Oauth2Params{
Client: args.Client,
Secret: args.Secret,
Scope: strings.Fields(args.Scope),
TokenUrl: u,
}
servicer, err := auth.NewOauth2(params, http.DefaultClient, secureStoragerTodo{})
if err != nil {
err = fmt.Errorf("could not init servicer: %s", err)
return
}
// call servicer, fetch the token
if token, err = servicer.Do(ctx); err != nil {
return
}
res = &oauth2AuthenticateResults{
AccessToken: token.AccessToken,
RefreshToken: token.RefreshToken,
Token: token,
}
return
}

View File

@ -0,0 +1,29 @@
functions:
authenticate:
meta:
short: "Authentication: OAUTH2"
params:
client:
required: true
types:
- { wf: String }
secret:
required: true
types:
- { wf: String }
scope:
required: true
types:
- { wf: String }
tokenUrl:
required: true
types:
- { wf: String }
results:
accessToken:
wf: String
refreshToken:
wf: String
token:
wf: Any

View File

@ -121,6 +121,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock
automation.LogHandler(Registry())
automation.QueueHandler(Registry())
automation.JsenvHandler(Registry())
automation.Oauth2Handler(Registry())
automation.LoopHandler(Registry(), DefaultWorkflow.parser)
automation.CorredorHandler(Registry(), corredor.Service())
automation.EmailHandler(Registry())