amplify-edge / packages

Flutter Packages
The Unlicense
2 stars 3 forks source link

#633 AuthService and AccountService protobuf definition #649

Closed WinWisely268 closed 4 years ago

WinWisely268 commented 4 years ago

611 and #633

Large commits, most of it are just generated protobuf services and definitions for flutter and golang.

To use it in maintemplate / sys-main, on golang side this is an example:

package main

import (
    "context"
    "flag"
    "fmt"
    authdeli "github.com/getcouragenow/packages/sys-account/delivery"
    authrepo "github.com/getcouragenow/packages/sys-account/pkg/auth"
    authutils "github.com/getcouragenow/packages/sys-account/pkg/utilities"
    "github.com/getcouragenow/packages/sys-account/rpc/v2"
    grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
    grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
    grpc_logrus "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus"
    grpcrecovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
    log "github.com/sirupsen/logrus"
    "google.golang.org/grpc/reflection"
    "net"
    "net/http"
    "os"
    "strings"
    "time"

    "golang.org/x/net/http2"
    "golang.org/x/net/http2/h2c"
    "google.golang.org/grpc"

    "github.com/improbable-eng/grpc-web/go/grpcweb"
)

type FileSystem struct {
    fs http.FileSystem
}

// Open opens file
func (fs FileSystem) Open(path string) (http.File, error) {
    f, err := fs.fs.Open(path)
    if err != nil {
        return nil, err
    }

    s, err := f.Stat()
    if s.IsDir() {
        index := strings.TrimSuffix(path, "/") + "/index.html"
        if _, err := fs.fs.Open(index); err != nil {
            return nil, err
        }
    }

    return f, nil
}

func recoveryHandler(l *log.Entry) func(panic interface{}) error {
    return func(panic interface{}) error {
        l.Warnf("maintemplate2 recovered, reason: %v", panic)
        return nil
    }
}

var port = flag.Int("port", 9074, "the port to serve on")
var local = flag.Bool("local", false, "flag for local development")
var directory = flag.String("dir", "../client/build/web/", "the directory of static file to host")

// legacy (V1)
// var natsAddr = flag.String("nats-server", "127.0.0.1", "nats server address")

func main() {
    flag.Parse()

    logger := log.New().WithField("svc", "maintemplate2")

    //
    // TODO @winwisely268: This will change once structure is finished
    // =========================================================================
    accessSecret, err := authutils.GenRandomByteSlice(32)
    if err != nil {
        log.Fatalf("error creating jwt access token secret: %v\n", err)
        os.Exit(1)
    }
    refreshSecret, err := authutils.GenRandomByteSlice(32)
    if err != nil {
        log.Fatalf("error creating jwt access token secret: %v\n", err)
        os.Exit(1)
    }
    tokenConfig := authrepo.NewTokenConfig(accessSecret, refreshSecret)
    //
    authDelivery := authdeli.AuthDelivery{
        Log:      logger,
        TokenCfg: tokenConfig,
        // TODO @winwisely268: UnauthenticatedRoutes should be sourced from database / config.
        UnauthenticatedRoutes: []string{
            "/proto.AuthService/Login",
            "/proto.AuthService/Register",
            "/proto.AuthService/ResetPassword",
            "/proto.AuthService/ForgotPassword",
            "/proto.AuthService/RefreshAccessToken",
            // debugging purposes
            "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo",
        },
    }
    // =========================================================================

    recoveryOptions := []grpcrecovery.Option{
        grpcrecovery.WithRecoveryHandler(recoveryHandler(logger)),
    }
    logrusOptions := []grpc_logrus.Option{
        grpc_logrus.WithLevels(grpc_logrus.DefaultCodeToLevel),
    }

    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
    defer cancel()

    opts := []grpc.ServerOption{grpc.MaxConcurrentStreams(10)}
    opts = append(opts)

    unaryInterceptors := []grpc.UnaryServerInterceptor{
        grpcrecovery.UnaryServerInterceptor(recoveryOptions...),
        grpc_logrus.UnaryServerInterceptor(logger, logrusOptions...),
        grpc_auth.UnaryServerInterceptor(authDelivery.DefaultInterceptor),
    }

    streamInterceptors := []grpc.StreamServerInterceptor{
        grpcrecovery.StreamServerInterceptor(recoveryOptions...),
        grpc_logrus.StreamServerInterceptor(logger, logrusOptions...),
        grpc_auth.StreamServerInterceptor(authDelivery.DefaultInterceptor),
    }

    grpcServer := grpc.NewServer(
        grpc_middleware.WithUnaryServerChain(unaryInterceptors...),
        grpc_middleware.WithStreamServerChain(streamInterceptors...),
    )

    // Register Services and Server Side reflection
    rpc.RegisterAuthServiceService(grpcServer, &rpc.AuthServiceService{
        Register:           authDelivery.Register,
        Login:              authDelivery.Login,
        ForgotPassword:     authDelivery.ForgotPassword,
        ResetPassword:      authDelivery.ResetPasssword,
        RefreshAccessToken: authDelivery.RefreshAccessToken,
    })

    // important to make sure tools like `grpcurl`, `grpc-ui`, `evans` or `grpc_cli` work
    reflection.Register(grpcServer)

    if *local {
        // fileServer := http.FileServer(FileSystem{http.Dir(*directory)})

        // adds websocket for evans
        grpcWebServer := grpcweb.WrapServer(
            grpcServer,
            grpcweb.WithCorsForRegisteredEndpointsOnly(false),
            grpcweb.WithWebsocketOriginFunc(func(req *http.Request) bool {
                return true
            }),
            grpcweb.WithWebsockets(true),
        )

        httpServer := &http.Server{
            Handler: h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                if r.ProtoMajor == 2 {
                    grpcWebServer.ServeHTTP(w, r)
                } else {
                    w.Header().Set("Access-Control-Allow-Origin", "*")
                    w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
                    w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-User-Agent, X-Grpc-Web")
                    w.Header().Set("grpc-status", "")
                    w.Header().Set("grpc-message", "")
                    // if grpcWebServer.IsGrpcWebRequest(r) {
                    logger.Infof("GRPC Request", r.URL)
                    grpcWebServer.ServeHTTP(w, r)
                    // } else {
                    //  fileServer.ServeHTTP(w, r)
                    // }
                }
            }), &http2.Server{}),
        }

        httpServer.Addr = fmt.Sprintf(":%d", *port)
        logger.Infof("server listening at %v\n", httpServer.Addr)
        err := httpServer.ListenAndServe()
        if err != nil {
            logger.Fatal(err)
        }

    } else {

        lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
        if err != nil {
            log.Fatalf("failed to listen: %v", err)
        }
        fmt.Printf("server listening at %v\n", lis.Addr())

        if err := grpcServer.Serve(lis); err != nil {
            log.Fatalf("failed to serve: %v", err)
        }
    }
}

Other minimal example

other minimal example is in server/cmd/authserver and server/cmd/authclient

To run example

screenshot_2020-09-24-062951

joe-getcouragenow commented 4 years ago

Could do please also add the code to sys-main, that can invoke your sys-account code ?

We can then run sys-main flutter in CI and go and so work up all our sys modules and make sure its all working before we start adding stuff to mod-main and maintemplate2

joe-getcouragenow commented 4 years ago

I will merge now anyway

WinWisely268 commented 4 years ago

Could do please also add the code to sys-main, that can invoke your sys-account code ?

We can then run sys-main flutter in CI and go and so work up all our sys modules and make sure its all working before we start adding stuff to mod-main and maintemplate2

Ok, will contact you for details