Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce solana auth integration #2

Merged
merged 1 commit into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
# and commit this file to your remote git repository to share the goodness with others.

tasks:
- init: go get && go build ./...

77 changes: 44 additions & 33 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,76 @@ package app

import (
"fmt"
"net/http"
"os"
"time"
"log"

_ "github.com/lib/pq"
"gorm.io/gorm"

"collection/config/envconfig"
"collection/domain"
"collection/dto"
"collection/logger"
"collection/service"
"github.com/jmoiron/sqlx"


"gorm.io/driver/postgres"

"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/gorilla/mux"
"github.com/joho/godotenv"
)

func Start(){
err := godotenv.Load("local.env")
if err != nil {
log.Fatalf("Some error occured. Err: %s", err)
}
func Start() {
envconfig.InitEnvVars()

r :=mux.NewRouter()
r := mux.NewRouter()

dbClient := getDbClient()
//wiring
newRepositoryDb := domain.NewUserRepositoryDb(dbClient)
newRepositoryDb := domain.NewUserRepositoryDb(dbClient.Model(&dto.User{}))
us := UserHandler{service.NewUserService(newRepositoryDb)}

r.HandleFunc("/collections",us.CreateCollection).Methods("Post")

address := os.Getenv("SERVER_ADDRESS")
port := os.Getenv("SERVER_PORT")
log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%s", address, port), r))

r.HandleFunc("/collections", us.CreateCollection).Methods("Post")
ginApp := gin.Default()

corsM := cors.New(cors.Config{AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type", "Authorization"},
AllowCredentials: false,
MaxAge: 12 * time.Hour,
AllowOrigins: envconfig.EnvVars.ALLOWED_ORIGIN})
ginApp.Use(corsM)
// api.ApplyRoutes(ginApp)
port := envconfig.EnvVars.APP_PORT
err := ginApp.Run(fmt.Sprintf(":%d", port))
if err != nil {
logger.Fatalf("failed to serve app on port %s: %s", port, err)
}

}

func getDbClient() *sqlx.DB{
func getDbClient() *gorm.DB {
dbUser := os.Getenv("DB_USER")
dbPasswd := os.Getenv("DB_PASSWD")
dbAddr := os.Getenv("DB_ADDR")
dbHost := os.Getenv("DB_HOST")
dbPort := os.Getenv("DB_PORT")
dbName := os.Getenv("DB_NAME")
db:= os.Getenv("DB")

dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?sslmode=disable", dbUser, dbPasswd, dbAddr, dbPort, dbName)
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable port=%s",
dbHost, dbUser, dbPasswd, dbName, dbPort)
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
logger.Fatalf("failed to connect to database: %s", err)
}

client, err := sqlx.Open(db, dataSource)
// Get underlying sql database to ping it
sqlDb, err := db.DB()
if err != nil {
panic(err)
logger.Fatalf("failed to ping database: %s", err)
}

// If ping fails then log error and exit
if err = sqlDb.Ping(); err != nil {
logger.Fatalf("failed to ping database: %s", err)
}
// See "Important settings" section.
client.SetConnMaxLifetime(time.Minute * 10)
client.SetMaxOpenConns(10)
client.SetMaxIdleConns(10)

logger.Info("Database is Connected")
return client
return db
}


52 changes: 52 additions & 0 deletions app/authenticate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package app

import (
"collection/dto/dtoapis"
"collection/internal/pkg/errorso"
"collection/logger"
"collection/service"
"errors"
"net/http"

"github.com/TheLazarusNetwork/go-helpers/httpo"
"github.com/gin-gonic/gin"
// "github.com/gorilla/mux"
)

func (u FlowIdHandler) Authenticate(c *gin.Context) {
var req dtoapis.AuthenticateRequest
err := c.BindJSON(&req)
if err != nil {
httpo.NewErrorResponse(http.StatusBadRequest, "failed to validate body").
Send(c, http.StatusBadRequest)
return
}

pasetoToken, err := u.service.VerifySignAndGetPaseto(req.Signature, req.FlowId)
if err != nil {
logger.Errorf("failed to get paseto: %s", err)

// If signature denied
if errors.Is(err, service.ErrSignDenied) {
httpo.NewErrorResponse(httpo.SignatureDenied, "signature denied").
Send(c, http.StatusUnauthorized)
return
}

if errors.Is(err, errorso.ErrRecordNotFound) {
httpo.NewErrorResponse(httpo.FlowIdNotFound, "flow id not found").
Send(c, http.StatusNotFound)
return
}

// If unexpected error
httpo.NewErrorResponse(500, "failed to verify and get paseto").Send(c, 500)
return
} else {
payload := dtoapis.AuthenticatePayload{
Token: pasetoToken,
}
httpo.NewSuccessResponse(http.StatusOK, "Token generated successfully", payload).
Send(c, http.StatusOK)
}
}
47 changes: 47 additions & 0 deletions app/flowid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package app

import (
"collection/config/envconfig"
"collection/dto/dtoapis"
"collection/logger"
"collection/service"
"net/http"

"github.com/TheLazarusNetwork/go-helpers/httpo"
"github.com/gin-gonic/gin"
"github.com/streamingfast/solana-go"
// "github.com/gorilla/mux"
)

type FlowIdHandler struct {
service service.DefaultFlowIdService
}

func (u FlowIdHandler) GetFlowId(c *gin.Context) {
walletAddress := c.Query("walletAddress")

if walletAddress == "" {
httpo.NewErrorResponse(http.StatusBadRequest, "wallet address (walletAddress) is required").
Send(c, http.StatusBadRequest)
return
}
_, err := solana.PublicKeyFromBase58(walletAddress)
if err != nil {
logger.Errorf("failed to get pubkey from wallet address (base58) %s: %s", walletAddress, err)
httpo.NewErrorResponse(httpo.WalletAddressInvalid, "failed to parse wallet address (walletAddress)").Send(c, http.StatusBadRequest)
return
}

flowId, err := u.service.CreateFlowId(walletAddress)
if err != nil {
logger.Errorf("failed to generate flow id: %s", err)
httpo.NewErrorResponse(http.StatusInternalServerError, "Unexpected error occured").Send(c, http.StatusInternalServerError)
return
}
userAuthEULA := envconfig.EnvVars.AUTH_EULA
payload := dtoapis.GetFlowIdPayload{
FlowId: flowId,
Eula: userAuthEULA,
}
httpo.NewSuccessResponse(http.StatusOK, "Flowid successfully generated", payload).Send(c, http.StatusOK)
}
34 changes: 34 additions & 0 deletions config/envconfig/envconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package envconfig

import (
"log"
"time"

"github.com/caarlos0/env/v6"
_ "github.com/joho/godotenv/autoload"
)

type config struct {
PASETO_PRIVATE_KEY string `env:"PASETO_PRIVATE_KEY,required"`
PASETO_EXPIRATION time.Duration `env:"PASETO_EXPIRATION,required"`

APP_PORT int `env:"APP_PORT,required"`
AUTH_EULA string `env:"AUTH_EULA,required"`
GIN_MODE string `env:"GIN_MODE,required"`
DB_HOST string `env:"DB_HOST,required"`
DB_USERNAME string `env:"DB_USERNAME,required"`
DB_PASSWORD string `env:"DB_PASSWORD,required"`
DB_NAME string `env:"DB_NAME,required"`
DB_PORT int `env:"DB_PORT,required"`
ALLOWED_ORIGIN []string `env:"ALLOWED_ORIGIN,required" envSeparator:","`
SIGNED_BY string `env:"SIGNED_BY,required"`
COLLECTION_PATH string `env:"COLLECTION_PATH,required"`
}

var EnvVars config = config{}

func InitEnvVars() {
if err := env.Parse(&EnvVars); err != nil {
log.Fatalf("failed to parse EnvVars: %s", err)
}
}
55 changes: 55 additions & 0 deletions domain/FlowIdRespository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package domain

import (
"collection/dto"
"collection/internal/pkg/errorso"

_ "github.com/lib/pq"
"gorm.io/gorm"
// _ "github.com/go-sql-driver/mysql"
)

type FlowIdRepositoryDb struct {
client *gorm.DB
}

func (i *FlowIdRepositoryDb) GetFlowId(flowId string) (*dto.FlowId, error) {
db := i.client
var userFlowId dto.FlowId
res := db.Find(&userFlowId, &dto.FlowId{
FlowId: flowId,
})

if err := res.Error; err != nil {
return nil, err
}

if res.RowsAffected == 0 {
return nil, errorso.ErrRecordNotFound
}
return &userFlowId, nil
}

// Adds flow id into database for given wallet Address
func (i *FlowIdRepositoryDb) AddFlowId(walletAddr string, flowId string) error {
db := i.client
err := db.Create(&dto.FlowId{
WalletAddress: walletAddr,
FlowId: flowId,
}).Error

return err
}

func (i *FlowIdRepositoryDb) DeleteFlowId(flowId string) error {
db := i.client
err := db.Delete(&dto.FlowId{
FlowId: flowId,
}).Error

return err
}

func NewFlowIdRepositoryDb(dbCLient *gorm.DB) FlowIdRepositoryDb {
return FlowIdRepositoryDb{dbCLient}
}
48 changes: 20 additions & 28 deletions domain/UserRepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,44 @@ package domain
import (
"collection/errs"
"collection/logger"
"strconv"

"collection/dto"

_ "github.com/lib/pq"

"gorm.io/gorm"
// _ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)

type UserRepositoryDb struct{
client *sqlx.DB
type UserRepositoryDb struct {
client *gorm.DB
}




func (d UserRepositoryDb)AddUser(c Collection,add []dto.Address)(*errs.AppError){
sqlInsert := `INSERT INTO "Collection"(user_id,name,symbol,description,total_supply,seller_fee,mint_price,game_resource,live_mint_start)values($,$,$,$,$,$,$,$,$)`
result,err := d.client.Exec(sqlInsert,c.User_id,c.Name,c.Symbol,c.Description,c.Total_supply,c.Seller_fee,c.Mint_price,c.Game_resource,c.Live_mint_start)
if err!=nil{
logger.Error("Error While creating new account for collection "+err.Error())
// return errs.NewUnexpectedError("Unexpected error from database")
return nil
}

id,err:=result.LastInsertId()
if err!=nil{
logger.Error("Error While getting last insert id"+err.Error())
func (d UserRepositoryDb) AddUser(c Collection, add []dto.Address) *errs.AppError {
collectionDb := d.client.Model(&Collection{})
err := collectionDb.Create(&c).Error
if err != nil {
logger.Error("Error While creating new account for collection " + err.Error())
// return errs.NewUnexpectedError("Unexpected error from database")
return nil
}

userId := strconv.FormatInt(id,10)
addInsert := "INSERT INTO Seller(user_id,address,share)values($,$,$)"
for _,v := range add{
_,err := d.client.Exec(addInsert,userId,v.Address,v.Share)
if err!=nil{
logger.Error("Error While creating new account"+err.Error())
sellerDb := d.client.Model(&Seller{})
for _, v := range add {
newSeller := Seller{
User_id: c.User_id,
Address: v.Address,
Share: v.Share,
}
err = sellerDb.Create(&newSeller).Error
if err != nil {
logger.Error("Error While creating new account" + err.Error())
// return errs.NewUnexpectedError("Unexpected error from database")
return nil
}
}
return nil
}

func NewUserRepositoryDb(dbCLient *sqlx.DB)UserRepositoryDb{
func NewUserRepositoryDb(dbCLient *gorm.DB) UserRepositoryDb {
return UserRepositoryDb{dbCLient}
}
}
Loading