B: Rework Model framework and finish vendor model so UI and callback controller can be built
This commit is contained in:
parent
b1a573b840
commit
ca70d241d6
|
@ -19,8 +19,8 @@ type MongoConfig struct {
|
||||||
var cfg *config
|
var cfg *config
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
viper.SetConfigName("config") // name of config file (without extension)
|
viper.SetConfigName("config") // name of config file (without extension)
|
||||||
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
||||||
viper.AddConfigPath("/etc/capstone") // path to look for the config file in
|
viper.AddConfigPath("/etc/capstone") // path to look for the config file in
|
||||||
|
|
||||||
err := viper.ReadInConfig()
|
err := viper.ReadInConfig()
|
||||||
|
|
|
@ -16,11 +16,11 @@ import (
|
||||||
var VALIDATE_EMAIL_REGEX = regexp.MustCompile(`^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$`)
|
var VALIDATE_EMAIL_REGEX = regexp.MustCompile(`^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$`)
|
||||||
|
|
||||||
type LoginPostBody struct {
|
type LoginPostBody struct {
|
||||||
Email string `json:"email"`
|
Email string `json:"email"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func SignUpHandler (c *gin.Context) {
|
func SignUpHandler(c *gin.Context) {
|
||||||
//get uname and password.
|
//get uname and password.
|
||||||
conf := config.Config()
|
conf := config.Config()
|
||||||
reqBody := &LoginPostBody{}
|
reqBody := &LoginPostBody{}
|
||||||
|
@ -80,16 +80,12 @@ func SignUpHandler (c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//add vendor accounts
|
|
||||||
|
|
||||||
mongo.AddAccountsForUser(user)
|
|
||||||
|
|
||||||
now := time.Now().Unix()
|
now := time.Now().Unix()
|
||||||
exp := time.Now().Add(12 * time.Hour).Unix()
|
exp := time.Now().Add(12 * time.Hour).Unix()
|
||||||
//build jwt
|
//build jwt
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256,
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256,
|
||||||
AuthClaims{
|
AuthClaims{
|
||||||
Subject: user.UserId,
|
Subject: user.MongoId().String(),
|
||||||
Expires: exp,
|
Expires: exp,
|
||||||
IssuedAt: now,
|
IssuedAt: now,
|
||||||
NotBefore: now,
|
NotBefore: now,
|
||||||
|
@ -107,7 +103,7 @@ func SignUpHandler (c *gin.Context) {
|
||||||
|
|
||||||
//store jwt as cookie
|
//store jwt as cookie
|
||||||
//TODO: Make sure set secure for prd deployment
|
//TODO: Make sure set secure for prd deployment
|
||||||
c.SetCookie("authorization", jwtStr, 3600 * 24, "", "", false, true)
|
c.SetCookie("authorization", jwtStr, 3600*24, "", "", false, true)
|
||||||
|
|
||||||
c.Redirect(302, "/dashboard")
|
c.Redirect(302, "/dashboard")
|
||||||
}
|
}
|
||||||
|
@ -163,7 +159,7 @@ func LoginHandler(c *gin.Context) {
|
||||||
//build jwt
|
//build jwt
|
||||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256,
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256,
|
||||||
AuthClaims{
|
AuthClaims{
|
||||||
Subject: user.UserId,
|
Subject: user.MongoId().String(),
|
||||||
Expires: exp,
|
Expires: exp,
|
||||||
IssuedAt: now,
|
IssuedAt: now,
|
||||||
NotBefore: now,
|
NotBefore: now,
|
||||||
|
@ -184,7 +180,7 @@ func LoginHandler(c *gin.Context) {
|
||||||
} else {
|
} else {
|
||||||
secure = true
|
secure = true
|
||||||
}
|
}
|
||||||
c.SetCookie("authorization", jwtStr, 3600 * 24, "", "", secure, true)
|
c.SetCookie("authorization", jwtStr, 3600*24, "", "", secure, true)
|
||||||
|
|
||||||
c.Redirect(302, "/dashboard")
|
c.Redirect(302, "/dashboard")
|
||||||
}
|
}
|
||||||
|
@ -198,7 +194,7 @@ func LogoutHandler(c *gin.Context) {
|
||||||
} else {
|
} else {
|
||||||
secure = true
|
secure = true
|
||||||
}
|
}
|
||||||
c.SetCookie("authorization", "", 3600 * 24, "", "", secure, true)
|
c.SetCookie("authorization", "", 3600*24, "", "", secure, true)
|
||||||
|
|
||||||
c.Redirect(302, "/login")
|
c.Redirect(302, "/login")
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,11 +73,11 @@ func AuthMiddleware(strict bool) gin.HandlerFunc {
|
||||||
return []byte(conf.JwtSecret), nil
|
return []byte(conf.JwtSecret), nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == jwt.ErrTokenExpired{
|
if err == jwt.ErrTokenExpired {
|
||||||
log.Warn("Redirecting, jwt expired")
|
log.Warn("Redirecting, jwt expired")
|
||||||
c.Redirect(301, "/login")
|
c.Redirect(301, "/login")
|
||||||
return
|
return
|
||||||
}else{
|
} else {
|
||||||
if strict {
|
if strict {
|
||||||
log.Warnf("Redirecting, jwt issue: %s", err)
|
log.Warnf("Redirecting, jwt issue: %s", err)
|
||||||
c.Redirect(301, "/login")
|
c.Redirect(301, "/login")
|
||||||
|
@ -89,8 +89,7 @@ func AuthMiddleware(strict bool) gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !parsedToken.Valid {
|
||||||
if !parsedToken.Valid {
|
|
||||||
if strict {
|
if strict {
|
||||||
log.Warn("Redirecting, jwt invalid")
|
log.Warn("Redirecting, jwt invalid")
|
||||||
c.Redirect(301, "/login")
|
c.Redirect(301, "/login")
|
||||||
|
|
|
@ -21,12 +21,12 @@ func BuildRouter(r *gin.Engine) {
|
||||||
|
|
||||||
log = logrus.New()
|
log = logrus.New()
|
||||||
log.SetFormatter(&logrus.TextFormatter{
|
log.SetFormatter(&logrus.TextFormatter{
|
||||||
ForceColors: true,
|
ForceColors: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
r.GET("/", AuthMiddleware(false), LandingPage)
|
r.GET("/", AuthMiddleware(false), LandingPage)
|
||||||
r.GET("/login", AuthMiddleware(false), LoginPage)
|
r.GET("/login", AuthMiddleware(false), LoginPage)
|
||||||
r.GET("/signup",AuthMiddleware(false), SignUpPage)
|
r.GET("/signup", AuthMiddleware(false), SignUpPage)
|
||||||
|
|
||||||
r.POST("/login", LoginHandler)
|
r.POST("/login", LoginHandler)
|
||||||
r.POST("/signup", SignUpHandler)
|
r.POST("/signup", SignUpHandler)
|
||||||
|
@ -36,7 +36,3 @@ func BuildRouter(r *gin.Engine) {
|
||||||
dashboard.Use(AuthMiddleware(true))
|
dashboard.Use(AuthMiddleware(true))
|
||||||
dashboard.GET("/", DashboardPage)
|
dashboard.GET("/", DashboardPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ func SignUpPage(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DashboardPage(c *gin.Context) {
|
func DashboardPage(c *gin.Context) {
|
||||||
|
//Get vendors
|
||||||
if raw, exists := c.Get(USER_OBJ_KEY); exists {
|
if raw, exists := c.Get(USER_OBJ_KEY); exists {
|
||||||
if user, ok := raw.(*models.User); ok {
|
if user, ok := raw.(*models.User); ok {
|
||||||
renderTempl(c, templates.DashboardPage(user))
|
renderTempl(c, templates.DashboardPage(user))
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Responds with 200ok and the rendered template
|
// Responds with 200ok and the rendered template
|
||||||
func renderTempl(c *gin.Context, tmpl templ.Component) {
|
func renderTempl(c *gin.Context, tmpl templ.Component) {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
buf := bytes.NewBuffer([]byte{})
|
||||||
tmpl.Render(c.Request.Context(), buf)
|
tmpl.Render(c.Request.Context(), buf)
|
||||||
|
@ -19,7 +19,6 @@ func badRequest(c *gin.Context, reason string) {
|
||||||
c.JSON(400, map[string]string{"error": reason})
|
c.JSON(400, map[string]string{"error": reason})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func serverError(c *gin.Context, reason string) {
|
func serverError(c *gin.Context, reason string) {
|
||||||
c.JSON(504, map[string]string{"error": reason})
|
c.JSON(504, map[string]string{"error": reason})
|
||||||
}
|
}
|
||||||
|
|
39
ui/db/db.go
39
ui/db/db.go
|
@ -2,14 +2,19 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"git.preston-baxter.com/Preston_PLB/capstone/frontend-service/config"
|
||||||
|
"git.preston-baxter.com/Preston_PLB/capstone/frontend-service/db/models"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Model interface {
|
type Model interface {
|
||||||
Save(client *mongo.Client) error
|
MongoId() primitive.ObjectID
|
||||||
Delete(client *mongo.Client) error
|
UpdateObjectInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
|
@ -26,5 +31,33 @@ func NewClient(uri string) (*DB, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) SaveModel(m Model) error {
|
func (db *DB) SaveModel(m Model) error {
|
||||||
return m.Save(db.client)
|
conf := config.Config()
|
||||||
|
|
||||||
|
opts := options.Update().SetUpsert(true)
|
||||||
|
res, err := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).UpdateOne(context.Background(), bson.M{"_id": m.MongoId()}, bson.M{"$set": m}, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.MatchedCount == 0 && res.ModifiedCount == 0 && res.UpsertedCount == 0 {
|
||||||
|
return errors.New("Failed to update vendor account properly")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) DeleteModel(m Model) error {
|
||||||
|
conf := config.Config()
|
||||||
|
|
||||||
|
opts := options.Delete()
|
||||||
|
res, err := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).DeleteOne(context.Background(), bson.M{"_id": m.MongoId()}, opts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.DeletedCount == 0 {
|
||||||
|
return errors.New("There was no item to delete")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,36 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.preston-baxter.com/Preston_PLB/capstone/frontend-service/config"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const USER_TYPE string = "user"
|
const USER_TYPE string = "user"
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
CommonFields `bson:"obj_info"`
|
*CommonFields `bson:"obj_info"`
|
||||||
mongoId primitive.ObjectID `bson:"_id,omitempty"`
|
mongoId primitive.ObjectID `bson:"_id,omitempty"`
|
||||||
UserId string `bson:"user_id,omitempty"`
|
Email string `bson:"email,omitempty"`
|
||||||
Email string `bson:"email,omitempty"`
|
PassowrdHash string `bson:"password_hash,omitempty"`
|
||||||
PassowrdHash string `bson:"password_hash,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Save(client *mongo.Client) error {
|
func (user *User) MongoId() primitive.ObjectID {
|
||||||
conf := config.Config()
|
|
||||||
|
|
||||||
if user.mongoId.IsZero() {
|
if user.mongoId.IsZero() {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
user.EntityType = USER_TYPE
|
|
||||||
user.CreatedAt = now
|
|
||||||
user.UpdatedAt = now
|
|
||||||
user.UserId = uuid.New().String()
|
|
||||||
user.mongoId = primitive.NewObjectIDFromTimestamp(now)
|
user.mongoId = primitive.NewObjectIDFromTimestamp(now)
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := options.Update().SetUpsert(true)
|
return user.mongoId
|
||||||
|
|
||||||
res, err := client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).UpdateOne(context.Background(), bson.M{"user_id": user.UserId}, bson.M{"$set": user},opts)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.MatchedCount == 0 && res.ModifiedCount == 0 && res.UpsertedCount == 0 {
|
|
||||||
return errors.New("Failed to update client properly")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) Delete(client *mongo.Client) error {
|
func (user *User) UpdateObjectInfo() {
|
||||||
conf := config.Config()
|
now := time.Now()
|
||||||
opts := options.Delete()
|
if user.CommonFields == nil {
|
||||||
|
user.CommonFields = new(CommonFields)
|
||||||
res, err := client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).DeleteOne(context.Background(), bson.M{"_id": user.mongoId}, opts)
|
user.EntityType = USER_TYPE
|
||||||
if err != nil {
|
user.CreatedAt = now
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
user.UpdatedAt = now
|
||||||
if res.DeletedCount == 0 {
|
|
||||||
return errors.New("There was no item to delete")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,46 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "go.mongodb.org/mongo-driver/bson/primitive"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
const VENDOR_TYPE = "vendor"
|
|
||||||
const VENDOR_ACCOUNT_TYPE = "vendor_account"
|
const VENDOR_ACCOUNT_TYPE = "vendor_account"
|
||||||
|
|
||||||
type Vendor struct {
|
type OauthCredential struct {
|
||||||
CommonFields `bson:"obj_info"`
|
AccessToken string `bson:"access_token,omitempty" json:"access_token,omitempty"`
|
||||||
mongoId primitive.ObjectID `bson:"_id,omitempty"`
|
ExpiresIn int `bson:"expires_in,omitempty" json:"expires_in,omitempty"`
|
||||||
VendorId string `bson:"vendor_id,omitempty"`
|
ExpiresAt time.Time `bson:"expires_at,omitempty" json:"expires_at,omitempty"`
|
||||||
Name string `bson:"name,omitempty"`
|
TokenType string `bson:"token_type,omitempty" json:"token_type,omitempty"`
|
||||||
OAuthUrl string `bson:"oauth_url"`
|
Scope string `bson:"scope,omitempty" json:"scope,omitempty"`
|
||||||
|
RefreshToken string `bson:"refresh_token,omitempty" json:"refresh_token,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type VendorAccount struct {
|
type VendorAccount struct {
|
||||||
CommonFields `bson:"obj_info"`
|
*CommonFields `bson:"obj_info"`
|
||||||
*Vendor
|
mongoId primitive.ObjectID `bson:"_id,omitempty"`
|
||||||
mongoId primitive.ObjectID `bson:"_id,omitempty"`
|
UserId primitive.ObjectID `bson:"user_id,omitempty"`
|
||||||
UserId string `bson:"user_id,omitempty"`
|
Secret string `bson:"secret,omitempty"`
|
||||||
Secret string `bson:"secret,omitempty"`
|
VendorId string `bson:"vendor_id,omitempty"`
|
||||||
VendorId string `bson:"vendor_id,omitempty"`
|
OauthCredentials *OauthCredential `bson:"ouath_credentials,omitempty"`
|
||||||
Authenticated bool `bson:"authenticated,omitempty"`
|
}
|
||||||
|
|
||||||
|
func (va *VendorAccount) MongoId() primitive.ObjectID {
|
||||||
|
if va.mongoId.IsZero() {
|
||||||
|
now := time.Now()
|
||||||
|
va.mongoId = primitive.NewObjectIDFromTimestamp(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
return va.mongoId
|
||||||
|
}
|
||||||
|
|
||||||
|
func (va *VendorAccount) UpdateObjectInfo() {
|
||||||
|
now := time.Now()
|
||||||
|
if va.CommonFields == nil {
|
||||||
|
va.CommonFields = new(CommonFields)
|
||||||
|
va.EntityType = VENDOR_ACCOUNT_TYPE
|
||||||
|
va.CreatedAt = now
|
||||||
|
}
|
||||||
|
va.UpdatedAt = now
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (db *DB) FindUserById(id string) (*models.User, error) {
|
||||||
conf := config.Config()
|
conf := config.Config()
|
||||||
|
|
||||||
opts := options.FindOne()
|
opts := options.FindOne()
|
||||||
res := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).FindOne(context.Background(), bson.M{"user_id": id, "obj_info.ent": models.USER_TYPE}, opts)
|
res := db.client.Database(conf.Mongo.EntDb).Collection(conf.Mongo.EntCol).FindOne(context.Background(), bson.M{"_id": id, "obj_info.ent": models.USER_TYPE}, opts)
|
||||||
|
|
||||||
if res.Err() != nil {
|
if res.Err() != nil {
|
||||||
if res.Err() == mongo.ErrNoDocuments {
|
if res.Err() == mongo.ErrNoDocuments {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"go.mongodb.org/mongo-driver/mongo/options"
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (db *DB) FindVendorAccountByUser(userId string) ([]models.VendorAccount, error){
|
func (db *DB) FindVendorAccountByUser(userId string) ([]models.VendorAccount, error) {
|
||||||
conf := config.Config()
|
conf := config.Config()
|
||||||
|
|
||||||
opts := options.Find()
|
opts := options.Find()
|
||||||
|
@ -26,4 +26,3 @@ func (db *DB) FindVendorAccountByUser(userId string) ([]models.VendorAccount, er
|
||||||
|
|
||||||
return vendors, nil
|
return vendors, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue