refactor: move vault package to app directory

This commit is contained in:
Prad Nukala
2024-12-09 18:39:57 -05:00
parent c158904efc
commit e3b8f2cffe
46 changed files with 15 additions and 15 deletions
+57
View File
@@ -0,0 +1,57 @@
package controller
import (
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/crypto/ucan/spec"
)
// ControllerConfig defines the configuration for UCAN middleware
type ControllerConfig struct {
// Skipper defines a function to skip middleware
Skipper func(c echo.Context) bool
// KeySource provides the source for validating UCANs
KeySource spec.KeyshareSource
// TokenLookup is a string in the form of "<source>:<name>" that is used
// to extract token from the request.
// Optional. Default value "header:Authorization".
// Possible values:
// - "header:<name>"
// - "query:<name>"
// - "param:<name>"
// - "cookie:<name>"
TokenLookup string
// AuthScheme to be used in the Authorization header.
// Optional. Default value "Bearer".
AuthScheme string
}
// DefaultControllerConfig is the default UCAN middleware config
var DefaultControllerConfig = ControllerConfig{
Skipper: nil,
TokenLookup: "header:Authorization",
AuthScheme: "Bearer",
}
type Option func(c *ControllerConfig)
func WithSkipper(skipper func(c echo.Context) bool) Option {
return func(c *ControllerConfig) {
c.Skipper = skipper
}
}
func WithAuthScheme(scheme string) Option {
return func(c *ControllerConfig) {
c.AuthScheme = scheme
}
}
// WithTokenLookup sets the token lookup strategy
func WithTokenLookup(lookup string) Option {
return func(c *ControllerConfig) {
c.TokenLookup = lookup
}
}
+122
View File
@@ -0,0 +1,122 @@
//go:build js && wasm
// +build js,wasm
package controller
import (
"fmt"
"strings"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/crypto/ucan/spec"
)
// Middleware returns middleware to validate Middleware tokens
func Middleware(source spec.KeyshareSource, opts ...Option) echo.MiddlewareFunc {
c := DefaultControllerConfig
for _, opt := range opts {
opt(&c)
}
c.KeySource = source
return initWithConfig(c)
}
// initWithConfig returns UCAN middleware with custom config
func initWithConfig(config ControllerConfig) echo.MiddlewareFunc {
// Defaults
if config.Skipper == nil {
config.Skipper = DefaultControllerConfig.Skipper
}
if config.TokenLookup == "" {
config.TokenLookup = DefaultControllerConfig.TokenLookup
}
if config.AuthScheme == "" {
config.AuthScheme = DefaultControllerConfig.AuthScheme
}
// Initialize
parts := strings.Split(config.TokenLookup, ":")
extractor := tokenFromHeader(parts[1], config.AuthScheme)
switch parts[0] {
case "query":
extractor = tokenFromQuery(parts[1])
case "param":
extractor = tokenFromParam(parts[1])
case "cookie":
extractor = tokenFromCookie(parts[1])
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
if config.Skipper != nil && config.Skipper(c) {
return next(c)
}
auth, err := extractor(c)
if err != nil {
return echo.NewHTTPError(401, err.Error())
}
parser := config.KeySource.UCANParser()
token, err := parser.ParseAndVerify(c.Request().Context(), auth)
if err != nil {
return echo.NewHTTPError(401, "invalid UCAN token")
}
// Store token in context
c.Set("ucan", token)
return next(c)
}
}
}
// tokenFromHeader extracts token from header
func tokenFromHeader(header string, authScheme string) func(echo.Context) (string, error) {
return func(c echo.Context) (string, error) {
auth := c.Request().Header.Get(header)
if auth == "" {
return "", fmt.Errorf("missing auth token")
}
if authScheme == "" {
return auth, nil
}
l := len(authScheme)
if len(auth) > l+1 && auth[:l] == authScheme {
return auth[l+1:], nil
}
return "", fmt.Errorf("invalid auth scheme")
}
}
// tokenFromQuery extracts token from query string
func tokenFromQuery(param string) func(echo.Context) (string, error) {
return func(c echo.Context) (string, error) {
token := c.QueryParam(param)
if token == "" {
return "", fmt.Errorf("missing auth token")
}
return token, nil
}
}
// tokenFromParam extracts token from url param
func tokenFromParam(param string) func(echo.Context) (string, error) {
return func(c echo.Context) (string, error) {
token := c.Param(param)
if token == "" {
return "", fmt.Errorf("missing auth token")
}
return token, nil
}
}
// tokenFromCookie extracts token from cookie
func tokenFromCookie(name string) func(echo.Context) (string, error) {
return func(c echo.Context) (string, error) {
cookie, err := c.Cookie(name)
if err != nil {
return "", fmt.Errorf("missing auth token")
}
return cookie.Value, nil
}
}
+2
View File
@@ -0,0 +1,2 @@
// Package didauth provides middleware and utilities for DID-based authentication
package didauth
+20
View File
@@ -0,0 +1,20 @@
package producer
import (
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/crypto/ucan"
"github.com/onsonr/sonr/crypto/ucan/store"
"github.com/onsonr/sonr/pkg/common/ipfs"
)
type ProducerContext struct {
echo.Context
// TokenParser is the attentuations assigned to the producer service
TokenParser *ucan.TokenParser
// TokenStore is the token store used to store and retrieve tokens
TokenStore store.IPFSTokenStore
// IPFSClient is the IPFS client used to resolve the UCAN
IPFSClient ipfs.Client
}
+38
View File
@@ -0,0 +1,38 @@
package producer
import (
"github.com/onsonr/sonr/crypto/mpc"
"github.com/onsonr/sonr/crypto/ucan"
"github.com/onsonr/sonr/crypto/ucan/store"
"github.com/onsonr/sonr/pkg/common/ipfs"
"github.com/labstack/echo/v4"
)
// Middleware returns middleware to spawn controllers and validate UCAN tokens
func Middleware(ipfs ipfs.Client, perms ucan.Permissions) echo.MiddlewareFunc {
// Setup token store and parser
store := store.NewIPFSTokenStore(ipfs)
parser := ucan.NewTokenParser(perms.GetConstructor(), store, store)
// Return middleware
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
ctx := ProducerContext{
Context: c,
IPFSClient: ipfs,
TokenParser: parser,
TokenStore: store,
}
return next(ctx)
}
}
}
func NewKeyset(c echo.Context) (mpc.Keyset, error) {
ks, err := mpc.NewKeyset()
if err != nil {
return nil, err
}
return ks, nil
}
+35
View File
@@ -0,0 +1,35 @@
package resolver
import (
"net/http"
"github.com/labstack/echo/v4"
"github.com/onsonr/sonr/app/gateway/config"
"google.golang.org/grpc"
)
type ClientsContext struct {
echo.Context
addr string
}
func GetClientConn(c echo.Context) (*grpc.ClientConn, error) {
cc, ok := c.(*ClientsContext)
if !ok {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "ClientsContext not found")
}
grpcConn, err := grpc.NewClient(cc.addr, grpc.WithInsecure())
if err != nil {
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Failed to dial gRPC")
}
return grpcConn, nil
}
func Middleware(env config.Env) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
cc := &ClientsContext{Context: c, addr: env.GetSonrGrpcUrl()}
return next(cc)
}
}
}
+41
View File
@@ -0,0 +1,41 @@
package resolver
import (
bankv1beta1 "cosmossdk.io/api/cosmos/bank/v1beta1"
"github.com/labstack/echo/v4"
didv1 "github.com/onsonr/sonr/api/did/v1"
dwnv1 "github.com/onsonr/sonr/api/dwn/v1"
svcv1 "github.com/onsonr/sonr/api/svc/v1"
)
func BankQueryClient(c echo.Context) (bankv1beta1.QueryClient, error) {
conn, err := GetClientConn(c)
if err != nil {
return nil, err
}
return bankv1beta1.NewQueryClient(conn), nil
}
func DIDQueryClient(c echo.Context) (didv1.QueryClient, error) {
conn, err := GetClientConn(c)
if err != nil {
return nil, err
}
return didv1.NewQueryClient(conn), nil
}
func DWNQueryClient(c echo.Context) (dwnv1.QueryClient, error) {
conn, err := GetClientConn(c)
if err != nil {
return nil, err
}
return dwnv1.NewQueryClient(conn), nil
}
func SVCQueryClient(c echo.Context) (svcv1.QueryClient, error) {
conn, err := GetClientConn(c)
if err != nil {
return nil, err
}
return svcv1.NewQueryClient(conn), nil
}