forked from thisisommore/aquire-company-backend
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2762ae8
Showing
32 changed files
with
948 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
tmp | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
image: | ||
file: .gitpod/Dockerfile | ||
tasks: | ||
- name: live | ||
init: | | ||
go get | ||
command: | | ||
docker run --name="backend" --rm -d -p 5432:5432 \ | ||
-e POSTGRES_PASSWORD=backend \ | ||
-e POSTGRES_USER=backend \ | ||
-e POSTGRES_DB=backend \ | ||
postgres -c log_statement=all | ||
sleep 12 | ||
gp sync-done db | ||
cp sample.env .env | ||
sed -i '/=$/d' .env | ||
air | ||
- name: postgres shell | ||
command: | | ||
gp sync-await db | ||
docker exec -it backend psql -U backend | ||
vscode: | ||
extensions: | ||
- golang.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
FROM gitpod/workspace-full | ||
|
||
USER gitpod | ||
RUN sudo curl -sSfL https://raw.githubusercontent.com/cosmtrek/air/master/install.sh | sudo sh -s -- -b $(go env GOPATH)/bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Package api provide support to create /api group | ||
package api | ||
|
||
import ( | ||
"template-app/api/auth" | ||
"template-app/api/publish" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
// ApplyRoutes applies the /api group and v1 routes to given gin Engine | ||
func ApplyRoutes(r *gin.Engine) { | ||
api := r.Group("/api") | ||
{ | ||
auth.ApplyRoutes(api) | ||
publish.ApplyRoutes(api) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Package auth provides Api to authenticate user by validating his supabase jwt and giving him paseto | ||
package auth | ||
|
||
import ( | ||
"errors" | ||
"net/http" | ||
"strings" | ||
"template-app/models/user/usermethods" | ||
"template-app/pkg/paseto" | ||
"template-app/pkg/supabase" | ||
|
||
"github.com/TheLazarusNetwork/go-helpers/httpo" | ||
"github.com/TheLazarusNetwork/go-helpers/logo" | ||
"github.com/gin-gonic/gin" | ||
"gorm.io/gorm" | ||
) | ||
|
||
// ApplyRoutes applies router to gin Router | ||
func ApplyRoutes(r *gin.RouterGroup) { | ||
g := r.Group("/supabase") | ||
{ | ||
g.POST("", supabaseAuth) | ||
} | ||
} | ||
|
||
func supabaseAuth(c *gin.Context) { | ||
var body AuthRequest | ||
err := c.BindJSON(&body) | ||
if err != nil { | ||
httpo.NewErrorResponse(http.StatusBadRequest, "failed to validate body"). | ||
Send(c, http.StatusBadRequest) | ||
return | ||
} | ||
// If unexpected error | ||
sbUser, err := supabase.GetSBUser(body.SupabaseToken) | ||
if err != nil { | ||
logo.Errorf("failed to get supabase user: %s", err) | ||
errMsg := "failed to verify and get paseto" | ||
if strings.Contains(err.Error(), "invalid JWT: unable to parse or verify signature, token is expired by ") { | ||
errMsg += ": supabase JWT token expired" | ||
} | ||
httpo.NewErrorResponse(500, errMsg).Send(c, 500) | ||
return | ||
} | ||
|
||
_, err = usermethods.Get(sbUser.Email) | ||
if err != nil { | ||
if errors.Is(err, gorm.ErrRecordNotFound) { | ||
err = usermethods.Add(sbUser.Email) | ||
if err != nil { | ||
logo.Errorf("failed to add user into database: %s", err) | ||
httpo.NewErrorResponse(500, "failed to verify and get paseto").Send(c, 500) | ||
return | ||
} | ||
} else { | ||
logo.Errorf("failed to check if user exist in database: %s", err) | ||
httpo.NewErrorResponse(500, "failed to verify and get paseto").Send(c, 500) | ||
return | ||
} | ||
} | ||
|
||
pasetoToken, err := paseto.GetPasetoForUser(sbUser.Email) | ||
if err != nil { | ||
logo.Errorf("failed to get paseto: %s", err) | ||
|
||
httpo.NewErrorResponse(500, "failed to verify and get paseto").Send(c, 500) | ||
return | ||
} | ||
|
||
payload := AuthPayload{ | ||
Token: pasetoToken, | ||
} | ||
httpo.NewSuccessResponseP(http.StatusOK, "token generated successfully", payload). | ||
SendD(c) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package auth | ||
|
||
type AuthRequest struct { | ||
SupabaseToken string `json:"supabaseToken"` | ||
} | ||
|
||
type AuthPayload struct { | ||
Token string `json:"token"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Package pasetomiddleware defines middleware to verify PASETO token with required claims | ||
package pasetomiddleware | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"template-app/pkg/paseto" | ||
|
||
"github.com/TheLazarusNetwork/go-helpers/httpo" | ||
"github.com/TheLazarusNetwork/go-helpers/logo" | ||
"github.com/vk-rv/pvx" | ||
"gorm.io/gorm" | ||
|
||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
var EmailIdInContext = "EmailId" | ||
var ( | ||
ErrAuthHeaderMissing = errors.New("authorization header is required") | ||
) | ||
|
||
func PASETO(c *gin.Context) { | ||
var headers GenericAuthHeaders | ||
err := c.BindHeader(&headers) | ||
if err != nil { | ||
err = fmt.Errorf("failed to bind header, %s", err) | ||
logValidationFailed(headers.Authorization, err) | ||
c.AbortWithStatus(http.StatusInternalServerError) | ||
return | ||
} | ||
if headers.Authorization == "" { | ||
logValidationFailed(headers.Authorization, ErrAuthHeaderMissing) | ||
httpo.NewErrorResponse(httpo.AuthHeaderMissing, ErrAuthHeaderMissing.Error()).Send(c, http.StatusBadRequest) | ||
c.Abort() | ||
return | ||
} | ||
emailId, err := paseto.VerifyPaseto(headers.Authorization) | ||
if err != nil { | ||
var validationErr *pvx.ValidationError | ||
if errors.As(err, &validationErr) { | ||
if validationErr.HasExpiredErr() { | ||
err = fmt.Errorf("failed to scan claims for paseto token, %s", err) | ||
logValidationFailed(headers.Authorization, err) | ||
httpo.NewErrorResponse(httpo.TokenExpired, "token expired").Send(c, http.StatusUnauthorized) | ||
c.Abort() | ||
return | ||
} | ||
} | ||
if errors.Is(err, gorm.ErrRecordNotFound) { | ||
c.AbortWithStatus(http.StatusUnauthorized) | ||
return | ||
} | ||
|
||
err = fmt.Errorf("failed to scan claims for paseto token, %s", err) | ||
logValidationFailed(headers.Authorization, err) | ||
c.AbortWithStatus(http.StatusUnauthorized) | ||
return | ||
} | ||
c.Set(EmailIdInContext, emailId) | ||
} | ||
|
||
func logValidationFailed(token string, err error) { | ||
logo.Warnf("validation failed with token %v and error: %v", token, err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package pasetomiddleware | ||
|
||
type GenericAuthHeaders struct { | ||
Authorization string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package publish | ||
|
||
import ( | ||
"net/http" | ||
"template-app/models/sitemodel" | ||
"template-app/models/sitemodel/site_model_methods" | ||
|
||
"github.com/TheLazarusNetwork/go-helpers/httpo" | ||
"github.com/gin-gonic/gin" | ||
) | ||
|
||
// ApplyRoutes applies router to gin Router | ||
func ApplyRoutes(r *gin.RouterGroup) { | ||
g := r.Group("/publish") | ||
{ | ||
g.POST("", publish) | ||
} | ||
} | ||
|
||
func publish(c *gin.Context) { | ||
var body PublishRequest | ||
err := c.BindJSON(&body) | ||
if err != nil { | ||
httpo.NewErrorResponse(http.StatusBadRequest, err.Error()). | ||
Send(c, http.StatusBadRequest) | ||
return | ||
} | ||
|
||
if err = site_model_methods.Add(&sitemodel.Site{Name: body.Name}); err != nil { | ||
httpo.NewErrorResponse(http.StatusInternalServerError, err.Error()). | ||
SendD(c) | ||
return | ||
} | ||
httpo.NewSuccessResponse(http.StatusOK, "site deployed successfully"). | ||
SendD(c) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package publish | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"template-app/app/stage/appinit" | ||
|
||
"github.com/gin-gonic/gin" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func Test_GetServices(t *testing.T) { | ||
appinit.Init() | ||
|
||
apiUrl := "/api/v1.0/orgadmin/org-service" | ||
reqBody := PublishRequest{ | ||
Name: "maxprerdomf78maaarrrrx", | ||
HtmlString: "<p>Hello Pro</p>", | ||
Components: []string{"3"}, | ||
} | ||
jsonBytes, err := json.Marshal(reqBody) | ||
require.Nil(t, err) | ||
|
||
rr := httptest.NewRecorder() | ||
req := httptest.NewRequest("POST", apiUrl, bytes.NewBuffer(jsonBytes)) | ||
c, _ := gin.CreateTestContext(rr) | ||
c.Request = req | ||
publish(c) | ||
require.Equal(t, http.StatusOK, rr.Result().StatusCode, rr.Body.String()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package publish | ||
|
||
type PublishRequest struct { | ||
Name string `json:"name" binding:"required"` | ||
HtmlString string `json:"htmlString"` | ||
Components []string `json:"components"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Package appinit provides method to Init all stages of app | ||
package appinit | ||
|
||
import ( | ||
"template-app/app/stage/appinit/dbconinit" | ||
"template-app/app/stage/appinit/dbmigrate" | ||
"template-app/app/stage/appinit/envinit" | ||
"template-app/app/stage/appinit/logoinit" | ||
) | ||
|
||
func Init() { | ||
envinit.Init() | ||
logoinit.Init() | ||
dbconinit.Init() | ||
dbmigrate.Migrate() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Package dbconinit provides method to Init database | ||
package dbconinit | ||
|
||
import ( | ||
"fmt" | ||
|
||
"template-app/pkg/envconfig" | ||
"template-app/pkg/store" | ||
|
||
"github.com/TheLazarusNetwork/go-helpers/logo" | ||
"gorm.io/driver/postgres" | ||
"gorm.io/gorm" | ||
) | ||
|
||
func Init() { | ||
var ( | ||
host = envconfig.EnvVars.DB_HOST | ||
username = envconfig.EnvVars.DB_USERNAME | ||
password = envconfig.EnvVars.DB_PASSWORD | ||
dbname = envconfig.EnvVars.DB_NAME | ||
port = envconfig.EnvVars.DB_PORT | ||
) | ||
|
||
dns := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable port=%d", | ||
host, username, password, dbname, port) | ||
|
||
var err error | ||
db, err := gorm.Open(postgres.New(postgres.Config{ | ||
DSN: dns, | ||
})) | ||
if err != nil { | ||
logo.Fatal("failed to connect database", err) | ||
} | ||
|
||
// Store database in global store | ||
store.DB = db | ||
|
||
// Get underlying sql database to ping it | ||
sqlDb, err := db.DB() | ||
if err != nil { | ||
logo.Fatal("failed to ping database", err) | ||
} | ||
|
||
// If ping fails then log error and exit | ||
if err = sqlDb.Ping(); err != nil { | ||
logo.Fatal("failed to ping database", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Package dbmigrate provides method to migrate models into database | ||
package dbmigrate | ||
|
||
import ( | ||
"template-app/models/sitemodel" | ||
"template-app/pkg/store" | ||
|
||
"github.com/TheLazarusNetwork/go-helpers/logo" | ||
) | ||
|
||
func Migrate() { | ||
db := store.DB | ||
err := db.AutoMigrate( | ||
&sitemodel.Site{}, | ||
) | ||
if err != nil { | ||
logo.Fatalf("failed to migrate models into database: %s", err) | ||
} | ||
} |
Oops, something went wrong.