commit d348bd323ec4db981d6247579070f453f4520cbb Author: nima Date: Mon Jan 8 16:06:31 2024 +0330 v1 diff --git a/config/.env b/config/.env new file mode 100644 index 0000000..e93c3f8 --- /dev/null +++ b/config/.env @@ -0,0 +1,7 @@ +DB_HOST="localhost" +DB_PORT=5432 +DB_USER="postgres" +DB_PASSWORD="1" +DB_NAME="cctv" + +SECRET = "uHkSNkpm5Uqr61IJt43Mow0lzRWdH2PTdylmK0pcg00oGrw0Ek3/406hRLIc7CglEY+aJy7zT//jfdqj2RQi6hxOfD4KWcS/3kEYmnuS92x9LPVvOeXS7BcAbsOkbk6EpbFNwcXdjYTpDDK88ZZhW/Tpqb/4cjBRUnemsHWCym/LXsBuoPWKrS5jKN8G0ehhErHogMZPu6FVY1uZ2bbX3YbRpTIp97CohlBIELUJCBGQzHloTM4JzJMGqMdBWlnA2DACHKeNT291jVDA/gn3Wcg9M/gIS3DUguuLXtB2pxl/RWMga6LqnPUntIp2l3wGiCLy2d6bSQLVESgTvVA5P55jYElAYq+3VD5NDJNrlAXER76ync5C3G6PEw0RPqWAMeA8OC2xIfjLAcbcvd8Ep3sacExXDiMTpXhyQv04h6M=" \ No newline at end of file diff --git a/data.txt b/data.txt new file mode 100644 index 0000000..3c07e53 --- /dev/null +++ b/data.txt @@ -0,0 +1,45 @@ +username +user info +passsword +email +phone number +address +product +procuct specs +description +price +quantity +garantee +orders +activity +recent pages +messages +wishlist +comments + + +entity : user - order - comment - prodcut - wishlist - user_profile - category + + + +user : username - address - email - password - user_id(PK) - phone_number - created_at - removed_at - updated_at +user_profile : autorize_code - birth_day - first_name - last_name - created_at - removed_at - updated_at - user_id(foreign_key) +prodcut : name - specs - price - description - quantity - garantee - product_id - created_at - removed_at - updated_at - category +orders : order_id - user_id(foreign_key) - date - product_id - price - created_at - removed_at - updated_at - quantity_ordered +wishlist : wishlist_id - product_id - created_at - removed_at - updated_at - user_id +comments : comments_id - comment_date - created_at - removed_at - updated_at - content - user_id - product_id + + + + +User Table: user_id (PK), username, email(unique), password, created_at, removed_at, updated_at , is_deleted , role +User Profile Table: user_profile_id (PK), authorize_code(unique), birth_day, first_name, last_name, created_at, updated_at, user_id (FK), is_deleted , removed_at +Phone Table : created_at, updated_at, user_id (FK), is_deleted , removed_at , Phone_id , +Product Table: product_id (PK), name, price, description, quantity, guarantee, created_at, removed_at, updated_at, category, is_deleted +Orders Table: order_id (PK), user_id (FK), date, product_id (FK), price, created_at, removed_at, updated_at, quantity_ordered, is_deleted +Wishlist Table: wishlist_id (PK), product_id (FK), created_at, removed_at, updated_at, user_id (FK), is_deleted +Comments Table: comments_id (PK), comment_date, created_at, removed_at, updated_at, content, user_id (FK), product_id (FK), is_deleted +specs Table : spec_id(PK) , product_id(FK) , type , value , is_deleted,created_at, removed_at, updated_at +address Table : address_id(PK) , user_id(FK) , address , created_at, removed_at, updated_at,is_deleted + + diff --git a/database/psql.go b/database/psql.go new file mode 100644 index 0000000..39d4ad1 --- /dev/null +++ b/database/psql.go @@ -0,0 +1,110 @@ +package database + +import ( + "fmt" + "os" + "strconv" + + models "app/models" + + "github.com/joho/godotenv" + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +func Db() gorm.DB { + err := godotenv.Load("./config/.env") + if err != nil { + panic(err) + } + + host := os.Getenv("DB_HOST") + port, err := strconv.Atoi(os.Getenv("DB_PORT")) + if err != nil { + fmt.Println(os.Getenv("DB_PORT")) + panic(err) + } + user := os.Getenv("DB_USER") + password := os.Getenv("DB_PASSWORD") + dbname := os.Getenv("DB_NAME") + + dbc := fmt.Sprintf("host=%s port=%d user=%s "+ + "password=%s dbname=%s sslmode=disable", + host, port, user, password, dbname) + + db, err := gorm.Open(postgres.Open(dbc), &gorm.Config{}) + if err != nil { + panic(err) + } + + return *db +} + +func Create_tables() { + db := Db() + + err := db.AutoMigrate(&models.User{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Address{}) + if err != nil { + panic(err) + } + err = db.AutoMigrate(&models.Phone{}) + if err != nil { + panic(err) + } + err = db.AutoMigrate(models.Product{}) + if err != nil { + panic(err) + } + err = db.AutoMigrate(&models.Order{}) + if err != nil { + panic(err) + } + err = db.AutoMigrate(models.Specs{}) + if err != nil { + panic(err) + } + err = db.AutoMigrate(&models.Comment{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Wishlist{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Order_products{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Images{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Jwt{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Carts{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.Cart_items{}) + if err != nil { + panic(err) + } + + err = db.AutoMigrate(&models.PriceHistory{}) + if err != nil { + panic(err) + } +} diff --git a/docs/docs.go b/docs/docs.go new file mode 100644 index 0000000..368204f --- /dev/null +++ b/docs/docs.go @@ -0,0 +1,142 @@ +// Code generated by swaggo/swag. DO NOT EDIT. + +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/users/": { + "post": { + "description": "Send UserModel", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "register" + ], + "summary": "Register User", + "parameters": [ + { + "description": "User Model", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.User" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.User" + } + }, + "400": { + "description": "Bad Request" + } + } + } + } + }, + "definitions": { + "models.User": { + "type": "object", + "properties": { + "birthDay": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "email": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "is_removed": { + "type": "boolean" + }, + "last_name": { + "type": "string" + }, + "national_code": { + "type": "string" + }, + "password": { + "type": "string" + }, + "postCode": { + "type": "string" + }, + "removed_at": { + "type": "string" + }, + "role": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } + } + }, + "securityDefinitions": { + "BasicAuth": { + "type": "basic" + } + }, + "externalDocs": { + "description": "OpenAPI", + "url": "https://swagger.io/resources/open-api/" + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost:8000", + BasePath: "", + Schemes: []string{}, + Title: "Swagger Example API", + Description: "This is a sample server celler server.", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/docs/swagger.json b/docs/swagger.json new file mode 100644 index 0000000..7ce93e8 --- /dev/null +++ b/docs/swagger.json @@ -0,0 +1,116 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server celler server.", + "title": "Swagger Example API", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "API Support", + "url": "http://www.swagger.io/support", + "email": "support@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0" + }, + "host": "localhost:8000", + "paths": { + "/users/": { + "post": { + "description": "Send UserModel", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "register" + ], + "summary": "Register User", + "parameters": [ + { + "description": "User Model", + "name": "user", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/models.User" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.User" + } + }, + "400": { + "description": "Bad Request" + } + } + } + } + }, + "definitions": { + "models.User": { + "type": "object", + "properties": { + "birthDay": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "email": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "is_removed": { + "type": "boolean" + }, + "last_name": { + "type": "string" + }, + "national_code": { + "type": "string" + }, + "password": { + "type": "string" + }, + "postCode": { + "type": "string" + }, + "removed_at": { + "type": "string" + }, + "role": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_id": { + "type": "integer" + }, + "username": { + "type": "string" + } + } + } + }, + "securityDefinitions": { + "BasicAuth": { + "type": "basic" + } + }, + "externalDocs": { + "description": "OpenAPI", + "url": "https://swagger.io/resources/open-api/" + } +} \ No newline at end of file diff --git a/docs/swagger.yaml b/docs/swagger.yaml new file mode 100644 index 0000000..4baa5fe --- /dev/null +++ b/docs/swagger.yaml @@ -0,0 +1,77 @@ +definitions: + models.User: + properties: + birthDay: + type: string + created_at: + type: string + email: + type: string + first_name: + type: string + is_removed: + type: boolean + last_name: + type: string + national_code: + type: string + password: + type: string + postCode: + type: string + removed_at: + type: string + role: + type: string + updated_at: + type: string + user_id: + type: integer + username: + type: string + type: object +externalDocs: + description: OpenAPI + url: https://swagger.io/resources/open-api/ +host: localhost:8000 +info: + contact: + email: support@swagger.io + name: API Support + url: http://www.swagger.io/support + description: This is a sample server celler server. + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: http://swagger.io/terms/ + title: Swagger Example API + version: "1.0" +paths: + /users/: + post: + consumes: + - application/json + description: Send UserModel + parameters: + - description: User Model + in: body + name: user + required: true + schema: + $ref: '#/definitions/models.User' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "400": + description: Bad Request + summary: Register User + tags: + - register +securityDefinitions: + BasicAuth: + type: basic +swagger: "2.0" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9757375 --- /dev/null +++ b/go.mod @@ -0,0 +1,49 @@ +module app + +go 1.19 + +require github.com/swaggo/echo-swagger v1.4.0 + +require github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca // indirect + +require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/PuerkitoBio/purell v1.2.0 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/spec v0.20.9 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang-jwt/jwt/v5 v5.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.3.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/labstack/echo v3.3.10+incompatible + github.com/labstack/echo-jwt/v4 v4.2.0 // indirect + github.com/labstack/echo/v4 v4.10.2 // indirect + github.com/labstack/gommon v0.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/swaggo/files/v2 v2.0.0 // indirect + github.com/swaggo/swag v1.16.1 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + golang.org/x/crypto v0.10.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.9.0 // indirect + golang.org/x/text v0.10.0 // indirect + golang.org/x/time v0.3.0 // indirect + golang.org/x/tools v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/driver/postgres v1.5.2 // indirect + gorm.io/gorm v1.25.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..88a0083 --- /dev/null +++ b/go.sum @@ -0,0 +1,161 @@ +github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.2.0 h1:/Jdm5QfyM8zdlqT6WVZU4cfP23sot6CEHA4CS49Ezig= +github.com/PuerkitoBio/purell v1.2.0/go.mod h1:OhLRTaaIzhvIyofkJfB24gokC7tM42Px5UhoT32THBk= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= +github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU= +github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca h1:aEyiDaExheG7fNpEYcILCVGgM7jlLzTVgxEQAGaepeM= +github.com/kavenegar/kavenegar-go v0.0.0-20221124112814-40341057b5ca/go.mod h1:CRhvvr4KNAyrg+ewrutOf+/QoHs7lztSoLjp+GqhYlA= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= +github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= +github.com/labstack/echo-jwt/v4 v4.2.0 h1:odSISV9JgcSCuhgQSV/6Io3i7nUmfM/QkBeR5GVJj5c= +github.com/labstack/echo-jwt/v4 v4.2.0/go.mod h1:MA2RqdXdEn4/uEglx0HcUOgQSyBaTh5JcaHIan3biwU= +github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= +github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= +github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/swaggo/echo-swagger v1.4.0 h1:RCxLKySw1SceHLqnmc41pKyiIeE+OiD7NSI7FUOBlLo= +github.com/swaggo/echo-swagger v1.4.0/go.mod h1:Wh3VlwjZGZf/LH0s81tz916JokuPG7y/ZqaqnckYqoQ= +github.com/swaggo/files/v2 v2.0.0 h1:hmAt8Dkynw7Ssz46F6pn8ok6YmGZqHSVLZ+HQM7i0kw= +github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM= +github.com/swaggo/swag v1.8.12 h1:pctzkNPu0AlQP2royqX3apjKCQonAnf7KGoxeO4y64w= +github.com/swaggo/swag v1.8.12/go.mod h1:lNfm6Gg+oAq3zRJQNEMBE66LIJKM44mxFqhEEgy2its= +github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg= +github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= +golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58= +golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= +gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= +gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= diff --git a/handlers/address.go b/handlers/address.go new file mode 100644 index 0000000..3c5c8ac --- /dev/null +++ b/handlers/address.go @@ -0,0 +1,123 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "fmt" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(a *models.Address) error +// GetAddresses(id uint) ([]models.Address, error) +// UpdateAddress(id uint, address string) error +// Delete(id uint) error + +func initAddress() *repositories.Address_repository { + db := database.Db() + addressRepository := new(repositories.Address_repository) + addressRepository.DB = &db + + return addressRepository +} + +func CreateAddress(c echo.Context) error { + + address := new(models.Address) + + if err := c.Bind(address); err != nil { + panic(err) + } + + addressRepository := initAddress() + + err := addressRepository.Create(address) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusCreated, address) +} + +func GetUserAddresses(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + addressRepository := initAddress() + + addresses, err := addressRepository.GetAddresses(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, addresses) +} + +func UpdateAddress(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewAddress string `json:"address"` + } + + addressRepository := initAddress() + + if update.NewAddress != "" { + err = addressRepository.UpdateAddress(update.NewAddress, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdatePostCode(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewPostCode string `json:"postcode"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + addressRepository := initAddress() + + if update.NewPostCode != "" { + err = addressRepository.UpdatePostCode(update.NewPostCode, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func DeleteAddress(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + addressRepository := initAddress() + + err = addressRepository.Delete(uint(id)) + if err != nil { + panic(err) + } + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/cart_items.go b/handlers/cart_items.go new file mode 100644 index 0000000..6959103 --- /dev/null +++ b/handlers/cart_items.go @@ -0,0 +1,153 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "app/utils" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +func initCartItems() *repositories.Cart_items_repository { + db := database.Db() + cartRepository := new(repositories.Cart_items_repository) + cartRepository.DB = &db + + return cartRepository +} + +func Create_cart_item(c echo.Context) error { + + db := database.Db() + + // get user's coockie + cookie, err := c.Cookie("authorization") + if err != nil { + return echo.ErrUnauthorized + } + // parse jwt token + token, err := utils.ParseToken(cookie.Value) + if err != nil { + return echo.ErrUnauthorized + } + // convert jwt content to int + jwtID, err := strconv.Atoi(token) + if err != nil { + return err + } + // check if user exists and return userID + userID, _, err := utils.CheckUserByJwt(uint(jwtID)) + if err != nil { + return err + } + + cartRepository := new(repositories.Carts_repository) + cartRepository.DB = &db + + cart, err := cartRepository.GetCart(userID) + if err != nil { + return err + } + + cart_items := new(models.Cart_items) + + cart_items.Cart_id = cart.Cart_id + //cart_items.Price = uint64(cart_items.Quantity) * cart_items. + + if err := c.Bind(cart_items); err != nil { + return err + } + + productRepository := new(repositories.Product_repository) + productRepository.DB = &db + product, err := productRepository.GetByID(cart_items.Product_id) + if err != nil { + panic(err) + } + + count, err := utils.GetProductCount(int64(cart_items.Product_id), cart_items.Cart_id) + if err != nil { + return err + } + + cartItemRepository := initCartItems() + + if count == 0 { + cart_items.Price = product.Price + cart_items.PricePerUnit = product.Price + err = cartItemRepository.Create(cart_items) + if err != nil { + return err + } + } else { + var certainItem models.Cart_items + err := db.Where("product_id = ?", cart_items.Product_id).Where("cart_id = ?", cart.Cart_id).Where("status = ?", "pending").First(&certainItem).Error + if err != nil { + return err + } + if certainItem.Quantity == product.Quantity { + return c.String(http.StatusNotAcceptable, "limit reached") + } + if certainItem.Quantity < product.Quantity { + err = cartItemRepository.IncreaseQuantity(certainItem.Cart_item_id) + if err != nil { + return err + } + } + + } + + return c.JSON(http.StatusCreated, cart_items) + +} + +func GetCartItems(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + return err + } + + cartRepository := initCartItems() + + items, err := cartRepository.GetItems(uint(id), "pending") + if err != nil { + return err + } + + return c.JSON(http.StatusAccepted, items) +} + +func UpdateItemStatus(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + return err + } + + cartRepository := initCartItems() + + err = cartRepository.UpdateStatus(uint(id)) + if err != nil { + return err + } + + return c.String(http.StatusAccepted, "updated") +} + +func Remove_cart_item(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + return err + } + + cartRepository := initCartItems() + + err = cartRepository.Remove(uint(id)) + if err != nil { + return err + } + + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/comment.go b/handlers/comment.go new file mode 100644 index 0000000..2d2f5b5 --- /dev/null +++ b/handlers/comment.go @@ -0,0 +1,113 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(c *models.Comment) error +// GetUserComments(id uint) ([]models.Comment, error) +// GetProductComments(id uint) ([]models.Comment, error) +// UpdateContent(id uint, content string) error +// Delete(id uint) error + +func initComment() *repositories.Comment_repository { + db := database.Db() + commentRepository := new(repositories.Comment_repository) + commentRepository.DB = &db + + return commentRepository +} + +func CreateComment(c echo.Context) error { + comment := new(models.Comment) + + if err := c.Bind(comment); err != nil { + panic(err) + } + + commentRepository := initComment() + + err := commentRepository.Create(comment) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusCreated, comment) + +} + +func GetUserComments(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + commentRepository := initComment() + + comments, err := commentRepository.GetUserComments(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, comments) +} + +func GetProductComments(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + commentRepository := initComment() + + comments, err := commentRepository.GetUserComments(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, comments) +} + +func UpdateComment(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewContent string `json:"content"` + } + + commentRepository := initComment() + + if update.NewContent != "" { + err = commentRepository.UpdateContent(uint(id), update.NewContent) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func DeleteComment(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + commentRepository := initComment() + + err = commentRepository.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/orders.go b/handlers/orders.go new file mode 100644 index 0000000..46180e2 --- /dev/null +++ b/handlers/orders.go @@ -0,0 +1,134 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(o *models.Order) error +// GetOrders(id uint) ([]models.Order, error) +// GetOrdersByDate(start time.Time, end time.Time) ([]models.Order, error) +// Delete(id uint) error + +type Status string + +const ( + StatusPending Status = "pending" + StatusPurchased Status = "purchased" + StatusRejected Status = "rejected" +) + +func initOrder() *repositories.Orders_repository { + db := database.Db() + orderRepository := new(repositories.Orders_repository) + orderRepository.DB = &db + + return orderRepository +} + +func getTotalPrice(items []models.Cart_items) uint64 { + var totalPrice uint64 + totalPrice = 0 + for i := 0; i < len(items); i++ { + totalPrice += items[i].Price + } + + return totalPrice +} + +func CreateOrder(c echo.Context, cart models.Carts, TransportationFee uint64) error { + db := database.Db() + order := new(models.Order) + var order_products []models.Order_products + itemsRepository := new(repositories.Cart_items_repository) + itemsRepository.DB = &db + // get cart_items related to this user + items, err := itemsRepository.GetItems(cart.Cart_id, string(StatusPurchased)) + if err != nil { + return err + } + orderRepository := initOrder() + order.User_id = cart.User_id + // calculate prices + order.ProductsTotalPrice = getTotalPrice(items) + tax := float64(getTotalPrice(items)) * 0.09 + order.Tax = uint64(tax) + order.TotalPrice = uint64(tax) + TransportationFee + getTotalPrice(items) + err = orderRepository.Create(order) + if err != nil { + panic(err) + } + + order_productsRepository := new(repositories.Order_Product_repository) + order_productsRepository.DB = &db + + productRepository := new(repositories.Product_repository) + productRepository.DB = &db + + for i := 0; i < len(items); i++ { + order_products[i].Order_id = order.Order_id + order_products[i].Product_id = items[i].Product_id + order_products[i].Quantity_ordered = items[i].Quantity + order_products[i].Price = items[i].Price + productQuantity, err := productRepository.GetQuantity(items[i].Product_id) + if err != nil { + return err + } + err = productRepository.UpdateQuantity(productQuantity-items[i].Quantity, items[i].Product_id) + if err != nil { + return err + } + err = order_productsRepository.Create(&order_products[i]) + if err != nil { + return err + } + } + + for i := 0; i < len(items); i++ { + itemsRepository.Remove(items[i].Cart_item_id) + } + + return c.JSON(http.StatusCreated, order) +} + +func GetUserOrders(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + orderRepository := initOrder() + + orders, err := orderRepository.GetOrders(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, orders) +} + +func GetOrdersByDate(c echo.Context) error { + + return c.String(http.StatusAccepted, "not ready") +} + +func DeleteOrder(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + orderRepository := initOrder() + + err = orderRepository.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/phone.go b/handlers/phone.go new file mode 100644 index 0000000..3a49604 --- /dev/null +++ b/handlers/phone.go @@ -0,0 +1,118 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(p *models.Phone) error +// GetPhones(id uint) (*models.Phone, error) +// UpdatePhoneNumber(number string, id uint) error +// UpdateCellPhone(number string, id uint) error +// Delete(id uint) error + +func initPhone() *repositories.Phone_repository { + db := database.Db() + phoneRepository := new(repositories.Phone_repository) + phoneRepository.DB = &db + + return phoneRepository +} + +func CreatePhone(c echo.Context) error { + phone := new(models.Phone) + + if err := c.Bind(phone); err != nil { + panic(err) + } + + phonerepository := initPhone() + + err := phonerepository.Create(phone) + if err != nil { + panic(err) + } + return c.JSON(http.StatusCreated, phone) +} + +func GetUserPhoneNumbers(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + phonerepository := initPhone() + + phone, err := phonerepository.GetPhones(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, phone) + +} + +func UpdatePhoneNumber(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewNumber string `json:"phonenumber"` + } + + phone := initPhone() + + if update.NewNumber != "" { + err = phone.UpdatePhoneNumber(update.NewNumber, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateCellPhoneNumber(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewNumber string `json:"cellphonenumber"` + } + + phone := initPhone() + + if update.NewNumber != "" { + err = phone.UpdateCellPhone(update.NewNumber, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func DeletePhone(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + phone := initPhone() + + err = phone.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") + +} diff --git a/handlers/product.go b/handlers/product.go new file mode 100644 index 0000000..5378fd0 --- /dev/null +++ b/handlers/product.go @@ -0,0 +1,259 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(p *models.Product) error +// GetByName(name string) ([]models.Product, error) +// GetByID(id uint) (*models.Product, error) +// GetByCategory(category string) ([]models.Product, error) +// UpdateName(name string, id uint) error +// UpdateDescription(content string, id uint) error +// UpdateWarranty(name string, id uint) error +// UpdateQuantity(quantity uint, id uint) error +// UpdateCategory(category string, id uint) error +// UpdatePrice(price uint64, id uint) error +// Delete(name string, id uint) error + +func initProduct() *repositories.Product_repository { + db := database.Db() + productRepository := new(repositories.Product_repository) + productRepository.DB = &db + + return productRepository +} + +func CreateProduct(c echo.Context) error { + + product := new(models.Product) + + if err := c.Bind(product); err != nil { + panic(err) + } + + productRepository := initProduct() + + err := productRepository.Create(product) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusCreated, product) +} + +func GetProductByName(c echo.Context) error { + name := c.Param("name") + productRepository := initProduct() + + product, err := productRepository.GetByName(name) + if err != nil { + return err + } + + return c.JSON(http.StatusAccepted, product) + +} + +func GetProductByID(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + productRepository := initProduct() + + product, err := productRepository.GetByID(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, product) +} + +func GetProductByCategory(c echo.Context) error { + name := c.Param("name") + productRepository := initProduct() + + product, err := productRepository.GetByCategory(name) + if err != nil { + return err + } + + return c.JSON(http.StatusAccepted, product) + +} + +func UpdateProductName(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewName string `json:"name"` + } + + if err := c.Bind(update); err != nil { + panic(err) + } + + product := initProduct() + + if update.NewName != "" { + err = product.UpdateName(update.NewName, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateDescription(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewDescription string `json:"description"` + } + + if err := c.Bind(update); err != nil { + panic(err) + } + + product := initProduct() + + if update.NewDescription != "" { + err = product.UpdateDescription(update.NewDescription, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateWarranty(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewWarranty string `json:"warranty"` + } + + if err := c.Bind(update); err != nil { + panic(err) + } + + product := initProduct() + + if update.NewWarranty != "" { + err = product.UpdateWarranty(update.NewWarranty, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateQuantity(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewQuantity uint `json:"description"` + } + + if err := c.Bind(update); err != nil { + panic(err) + } + + product := initProduct() + + err = product.UpdateQuantity(update.NewQuantity, uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateCategory(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewCategory string `json:"category"` + } + + if err := c.Bind(update); err != nil { + panic(err) + } + + product := initProduct() + + if update.NewCategory != "" { + err = product.UpdateCategory(update.NewCategory, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdatePrice(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewPrie uint64 `json:"price"` + } + + if err := c.Bind(update); err != nil { + panic(err) + } + + product := initProduct() + + err = product.UpdatePrice(update.NewPrie, uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "updated") +} + +func DeleteProduct(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + product := initProduct() + + err = product.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/specs.go b/handlers/specs.go new file mode 100644 index 0000000..9b29935 --- /dev/null +++ b/handlers/specs.go @@ -0,0 +1,118 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(s *models.Specs) error +// GetSpecs(id uint) (*models.Specs, error) +// UpdateType(newType string, id uint) error +// UpdateValue(newValue string, id uint) error +// Delete(id uint) error + +func initSpecs() *repositories.Specs_repository { + db := database.Db() + specsRepository := new(repositories.Specs_repository) + specsRepository.DB = &db + + return specsRepository +} + +func CreateSpecs(c echo.Context) error { + spec := new(models.Specs) + + specsRepository := initSpecs() + + if err := c.Bind(spec); err != nil { + panic(err) + } + + err := specsRepository.Create(spec) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusCreated, spec) + +} + +func GetSpecs(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + specsRepository := initSpecs() + + specs, err := specsRepository.GetSpecs(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, specs) + +} + +func UpdateType(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewType string `json:"type"` + } + specsRepository := initSpecs() + + if update.NewType != "" { + err = specsRepository.UpdateType(update.NewType, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateValue(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewValue string `json:"value"` + } + specsRepository := initSpecs() + + if update.NewValue != "" { + err = specsRepository.UpdateValue(update.NewValue, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func DeleteSpecs(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + specsRepository := initSpecs() + + err = specsRepository.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/user.go b/handlers/user.go new file mode 100644 index 0000000..f41f8f8 --- /dev/null +++ b/handlers/user.go @@ -0,0 +1,368 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "app/utils" + "net/http" + "strconv" + + "fmt" + + "github.com/labstack/echo/v4" +) + +func initUser() *repositories.User_repository { + db := database.Db() + userRepository := new(repositories.User_repository) + userRepository.DB = &db + + return userRepository +} + +// RegisterUser godoc +// @Summary Register User +// @Description Send UserModel +// @Tags register +// @Accept json +// @Produce json +// @Param user body models.User true "User Model" +// @Success 200 {object} models.User +// @Failure 400 +// @Router /users/ [post] +func RegisterUser(c echo.Context) error { + + user := new(models.User) + db := database.Db() + if err := c.Bind(user); err != nil { + return err + } + + userRepository := initUser() + user.Role = "user" + err := userRepository.Create(user) + if err != nil { + return err + } + + tempUser, err := utils.GetByPhoneNumber(user.CellPhone_number) + if err != nil { + return err + } + cartRepository := new(repositories.Carts_repository) + cartRepository.DB = &db + cart := new(models.Carts) + cart.User_id = tempUser.User_id + err = cartRepository.Create(cart) + if err != nil { + return err + } + + //utils.GenerateToken(c,*user) + + return c.JSON(http.StatusCreated, user) +} + +func GetSameUserNames(c echo.Context) error { + username := c.Param("name") + userRepository := initUser() + + users, err := userRepository.GetByName(username) + if err != nil { + return err + } + + return c.JSON(http.StatusAccepted, users) + +} + +func GetUserByID(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + userRepository := initUser() + + user, err := userRepository.GetByID(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, user) +} + +// UpdateUserName(name string, id uint) error +// UpdateEmail(email string, id uint) error +// UpdatePassword(password string, id uint) error +// UpdateRole(newRole string, id uint) error +// UpdateNationalCode(newCode string, id uint) error +// UpdateBirthDay(newBirthDay string, id uint) error +// UpdateFirstName(firstName string, id uint) error +// UpdateLastName(lastName string, id uint) error +// UpdatePostCode(newPostCode string, id uint) error +// Delete(name string, id uint) error + +func UpdateUserName(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewUsername string `json:"username"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + err = userRepository.UpdateUserName(update.NewUsername, uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateEmail(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewEmail string `json:"email"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + if update.NewEmail != "" { + err = userRepository.UpdateEmail(update.NewEmail, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdatePassword(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + isNull := true + + var update struct { + OldPassword string `json:"oldpassword"` + NewPassword string `json:"password"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + user, err := userRepository.GetByID(uint(id)) + if err != nil { + return err + } + + if user.Password != "" { + isNull = false + } + + if isNull { + password, err := utils.HashPW(update.NewPassword) + if err != nil { + return err + } + err = userRepository.UpdatePassword(password, uint(id)) + if err != nil { + panic(err) + } + } else { + checkpw, err := utils.Match(update.OldPassword, user.Email) + if err != nil { + return err + } + + if checkpw { + password, err := utils.HashPW(update.NewPassword) + if err != nil { + return err + } + err = userRepository.UpdatePassword(password, uint(id)) + if err != nil { + panic(err) + } + } + + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateRole(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + var update struct { + NewRole string `json:"role"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + if update.NewRole != "" { + err = userRepository.UpdateRole(update.NewRole, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateNationalCode(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewNationalCode string `json:"national_code"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + if update.NewNationalCode != "" { + err = userRepository.UpdateNationalCode(update.NewNationalCode, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateBirthDay(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewBirthDay string `json:"birthday"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + if update.NewBirthDay != "" { + err = userRepository.UpdateBirthDay(update.NewBirthDay, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateFirstName(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewFirstName string `json:"firstname"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + if update.NewFirstName != "" { + err = userRepository.UpdateFirstName(update.NewFirstName, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func UpdateLastName(c echo.Context) error { + + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + var update struct { + NewLastName string `json:"lastname"` + } + + if err := c.Bind(&update); err != nil { + panic(err) + } + + userRepository := initUser() + + if update.NewLastName != "" { + err = userRepository.UpdateLastName(update.NewLastName, uint(id)) + if err != nil { + panic(err) + } + } + + return c.String(http.StatusAccepted, "updated") +} + +func DeleteUser(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + fmt.Println(err) + } + + userRepository := initUser() + + err = userRepository.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") +} diff --git a/handlers/wishlist.go b/handlers/wishlist.go new file mode 100644 index 0000000..603d4b3 --- /dev/null +++ b/handlers/wishlist.go @@ -0,0 +1,74 @@ +package handlers + +import ( + database "app/database" + "app/models" + "app/repositories" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +// Create(w *models.Wishlist) error +// GetList(id uint) ([]models.Wishlist, error) +// Delete(id uint) error + +func initWishlist() *repositories.Wishlist_repository { + db := database.Db() + wishRepository := new(repositories.Wishlist_repository) + wishRepository.DB = &db + + return wishRepository +} + +func CreateWishlist(c echo.Context) error { + wishlist := new(models.Wishlist) + wishlistReposiory := initWishlist() + + if err := c.Bind(wishlist); err != nil { + panic(err) + } + + err := wishlistReposiory.Create(wishlist) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusCreated, wishlist) + +} + +func GetWishlist(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + wishlistReposiory := initWishlist() + + wishlist, err := wishlistReposiory.GetList(uint(id)) + if err != nil { + panic(err) + } + + return c.JSON(http.StatusAccepted, wishlist) + +} + +func DeleteWishlist(c echo.Context) error { + id, err := strconv.Atoi(c.Param("id")) + if err != nil { + panic(err) + } + + wishlistReposiory := initWishlist() + + err = wishlistReposiory.Delete(uint(id)) + if err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "removed") + +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..1bb87cf --- /dev/null +++ b/main.go @@ -0,0 +1,43 @@ +package main + +import ( + db "app/database" + + _ "app/docs" + route "app/router" + + "github.com/labstack/echo/v4" + echoSwagger "github.com/swaggo/echo-swagger" +) + +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server celler server. +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8000 + +// @securityDefinitions.basic BasicAuth + +// @externalDocs.description OpenAPI +// @externalDocs.url https://swagger.io/resources/open-api/ +func main() { + + db.Create_tables() + + e := echo.New() + e.GET("/swagger/*", echoSwagger.WrapHandler) + + route.UserRoutes(e) + route.ProductRoutes(e) + route.CartRoutes(e) + route.LoginLogout(e) + e.Logger.Fatal(e.Start(":8000")) +} diff --git a/middlewares/adminOnly.go b/middlewares/adminOnly.go new file mode 100644 index 0000000..ebfb024 --- /dev/null +++ b/middlewares/adminOnly.go @@ -0,0 +1,55 @@ +package middlewares + +import ( + "app/database" + "app/models" + "app/utils" + "net/http" + "strconv" + + "github.com/labstack/echo/v4" +) + +func AdminOnly() echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + cookie, err := c.Cookie("authorization") + if err != nil { + return err + } + token, err := utils.ParseToken(cookie.Value) + if err != nil { + return err + } + + id, err := strconv.Atoi(token) + if err != nil { + return err + } + + _, checkuser, err := utils.CheckUserByJwt(uint(id)) + if err != nil { + return err + } + + if !checkuser { + return echo.ErrNotFound + } + + user := new(models.User) + + db := database.Db() + + if err := db.Where("is_removed = ?", false).Where("user_id = ?", id).First(user).Error; err != nil { + return err + } + + // Check if the user has the admin role + if user.Role != "admin" { + return echo.NewHTTPError(http.StatusForbidden, "Access denied") + } + + return next(c) + } + } +} diff --git a/models/Order_products.go b/models/Order_products.go new file mode 100644 index 0000000..9772986 --- /dev/null +++ b/models/Order_products.go @@ -0,0 +1,17 @@ +package models + +import "time" + +type Order_products struct { + Order_products_id uint `gorm:"primaryKey"` + Order_id uint + Order Order `gorm:"references:Order_id"` + Product_id uint + Product Product `gorm:"references:Product_id"` + Price uint64 + Quantity_ordered uint + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/address.go b/models/address.go new file mode 100644 index 0000000..1c4543e --- /dev/null +++ b/models/address.go @@ -0,0 +1,16 @@ +package models + +import "time" + +type Address struct { + Address_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` + Address string `gorm:"type:TEXT"` + PostCode string `gorm:"type:varchar(10)"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_active bool + Is_removed bool `gorm:"default:false"` +} diff --git a/models/cart_items.go b/models/cart_items.go new file mode 100644 index 0000000..b8ff21b --- /dev/null +++ b/models/cart_items.go @@ -0,0 +1,18 @@ +package models + +import "time" + +type Cart_items struct { + Cart_item_id uint `gorm:"primaryKey"` + Cart_id uint + Cart Carts `gorm:"references:Cart_id"` + Product_id uint + Product Product `gorm:"references:Product_id"` + Quantity uint `gorm:"default:1"` + PricePerUnit uint64 + Price uint64 + Status string `gorm:"default:pending"` + Created_at time.Time + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/carts.go b/models/carts.go new file mode 100644 index 0000000..56a103f --- /dev/null +++ b/models/carts.go @@ -0,0 +1,12 @@ +package models + +import "time" + +type Carts struct { + Cart_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` + Created_at time.Time + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/comments.go b/models/comments.go new file mode 100644 index 0000000..b77bc92 --- /dev/null +++ b/models/comments.go @@ -0,0 +1,16 @@ +package models + +import "time" + +type Comment struct { + Comment_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` + Product_id uint + Product Product `gorm:"references:Product_id"` + Content string `gorm:"type:TEXT"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/images.go b/models/images.go new file mode 100644 index 0000000..5848103 --- /dev/null +++ b/models/images.go @@ -0,0 +1,14 @@ +package models + +import "time" + +type Images struct { + Img_id uint `gorm:"primary"` + Product_id uint + Product Product `gorm:"references:Product_id"` + Address string `gorm:"type:varchar(255)"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/jwt.go b/models/jwt.go new file mode 100644 index 0000000..4f786d4 --- /dev/null +++ b/models/jwt.go @@ -0,0 +1,7 @@ +package models + +type Jwt struct { + Jwt_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` +} diff --git a/models/jwtClaims.go b/models/jwtClaims.go new file mode 100644 index 0000000..5ace92e --- /dev/null +++ b/models/jwtClaims.go @@ -0,0 +1,8 @@ +package models + +import "github.com/golang-jwt/jwt/v5" + +type JwtClaims struct { + Jwt_id uint `json:"jwtID"` + jwt.RegisteredClaims +} diff --git a/models/orders.go b/models/orders.go new file mode 100644 index 0000000..6852ac5 --- /dev/null +++ b/models/orders.go @@ -0,0 +1,32 @@ +package models + +import "time" + +// type Order struct { +// Order_id uint `gorm:"primaryKey"` +// User_id uint +// UserRef User `gorm:"foreignKey:User_id"` +// Procuct_id uint +// ProductRef Product `gorm:"foreignKey:Product_id"` +// Price uint64 +// Quantity_ordered uint +// Order_date time.Time +// Created_at time.Time +// Updated_at time.Time +// Removed_at time.Time +// Is_removed bool `gorm:"default:false"` +// } + +type Order struct { + Order_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` + TransportationFee uint64 + Tax uint64 + ProductsTotalPrice uint64 + TotalPrice uint64 + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/phone.go b/models/phone.go new file mode 100644 index 0000000..771457b --- /dev/null +++ b/models/phone.go @@ -0,0 +1,15 @@ +package models + +import "time" + +type Phone struct { + Phone_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` + Phone_number string `gorm:"type:varchar(11)"` + BackUp_nummber string `gorm:"type:varchar(11)"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/priceHistory.go b/models/priceHistory.go new file mode 100644 index 0000000..a6b806a --- /dev/null +++ b/models/priceHistory.go @@ -0,0 +1,13 @@ +package models + +import "time" + +type PriceHistory struct { + Price_id uint + Product_id uint + Product Product `gorm:"references:Product_id"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/product.go b/models/product.go new file mode 100644 index 0000000..312acc0 --- /dev/null +++ b/models/product.go @@ -0,0 +1,17 @@ +package models + +import "time" + +type Product struct { + Product_id uint `gorm:"primaryKey"` + Name string `gorm:"type:varchar(255)"` + Description string `gorm:"type:TEXT"` + Warranty string `gorm:"type:varchar(255)"` + Quantity uint + Category string `gorm:"type:varchar(255)"` + Price uint64 + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/specs.go b/models/specs.go new file mode 100644 index 0000000..969fac8 --- /dev/null +++ b/models/specs.go @@ -0,0 +1,15 @@ +package models + +import "time" + +type Specs struct { + Specs_id uint `gorm:"primaryKey"` + Product_id uint + Product Product `gorm:"references:Product_id"` + Type string `gorm:"type:varchar(255)"` + Value string `gorm:"type:varchar(255)"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/user.go b/models/user.go new file mode 100644 index 0000000..9598e7b --- /dev/null +++ b/models/user.go @@ -0,0 +1,20 @@ +package models + +import "time" + +type User struct { + User_id uint `gorm:"primaryKey"` + Username string `gorm:"type:varchar(100)"` + Email string `gorm:"type:varchar(255)"` + Password string `gorm:"type:varchar(255)"` + CellPhone_number string `gorm:"unique;type:varchar(11)"` + Role string `gorm:"type:varchar(50)"` + National_code string `gorm:"type:varchar(10)"` + BirthDay string `gorm:"type:varchar(255)"` + First_name string `gorm:"type:varchar(50)"` + Last_name string `gorm:"type:varchar(50)"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/models/wishlist.go b/models/wishlist.go new file mode 100644 index 0000000..56356c7 --- /dev/null +++ b/models/wishlist.go @@ -0,0 +1,15 @@ +package models + +import "time" + +type Wishlist struct { + Wishlist_id uint `gorm:"primaryKey"` + User_id uint + User User `gorm:"references:User_id"` + Product_id uint + Product Product `gorm:"references:Product_id"` + Created_at time.Time + Updated_at time.Time `gorm:"default:null"` + Removed_at time.Time `gorm:"default:null"` + Is_removed bool `gorm:"default:false"` +} diff --git a/repositories/Address.go b/repositories/Address.go new file mode 100644 index 0000000..eed1229 --- /dev/null +++ b/repositories/Address.go @@ -0,0 +1,64 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Address interface { + Create(a *models.Address) error + GetAddresses(id uint) ([]models.Address, error) + UpdateAddress(address string, id uint) error + UpdatePostCode(newPostCode string, id uint) error + Delete(id uint) error +} + +type Address_repository struct { + DB *gorm.DB +} + +func newAddressRepository(db *gorm.DB) Address { + return &Address_repository{DB: db} +} + +func (r *Address_repository) Create(address *models.Address) error { + if err := r.DB.Create(&address).Error; err != nil { + return err + } + return nil +} + +func (r *Address_repository) GetAddresses(id uint) ([]models.Address, error) { + var address []models.Address + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&address).Error; err != nil { + return nil, err + } + return address, nil +} + +func (r *Address_repository) UpdateAddress(newAddress string, id uint) error { + var address models.Address + if err := r.DB.Where("is_removed = ?", false).Where("address_id = ? ", id).Model(&address).Update("address", newAddress).Error; err != nil { + return err + } + return nil +} + +func (r *Address_repository) UpdatePostCode(newPostCode string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("address_id = ? ", id).Model(&user).Update("post_code", newPostCode).Error; err != nil { + return err + } + return nil +} + +func (r *Address_repository) Delete(id uint) error { + var address models.Address + if err := r.DB.Where("address_id = ?", id).Model(&address).Update("is_removed", true).Error; err != nil { + return err + } + + return nil + +} diff --git a/repositories/Cart_items.go b/repositories/Cart_items.go new file mode 100644 index 0000000..b8828ac --- /dev/null +++ b/repositories/Cart_items.go @@ -0,0 +1,100 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Carts_items interface { + Create(*models.Cart_items) error + GetItems(id uint, status string) ([]models.Cart_items, error) + IncreaseQuantity(id uint) error + DecreaseQuantity(id uint) error + UpdateStatus(id uint) error + Remove(id uint) error +} + +type Cart_items_repository struct { + DB *gorm.DB +} + +func newCartsItemsRepository(db *gorm.DB) Carts_items { + return &Cart_items_repository{DB: db} +} + +func (r *Cart_items_repository) Create(cart_items *models.Cart_items) error { + if err := r.DB.Create(&cart_items).Error; err != nil { + return err + } + + return nil +} + +func (r *Cart_items_repository) GetItems(id uint, status string) ([]models.Cart_items, error) { + var items []models.Cart_items + if err := r.DB.Where("is_removed = ?", false).Where("cart_id = ? ", id).Where("status = ?", status).Find(&items).Error; err != nil { + return nil, err + } + + return items, nil +} + +func (r *Cart_items_repository) IncreaseQuantity(id uint) error { + var item models.Cart_items + if err := r.DB.Where("is_removed = ?", false).Where("status = ? ", "pending").Where("cart_item_id = ?", id).First(&item).Error; err != nil { + return err + } + + quantity := item.Quantity + 1 + + if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&item).Update("quantity", quantity).Error; err != nil { + return err + } + + if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&item).Update("price", item.PricePerUnit*uint64(quantity)).Error; err != nil { + return err + } + + return nil +} + +func (r *Cart_items_repository) DecreaseQuantity(id uint) error { + var item, temp models.Cart_items + if err := r.DB.Where("is_removed = ?", false).Where("status = pending").Where("cart_item_id = ?", id).First(&item).Error; err != nil { + return err + } + + if item.Quantity > 1 { + quantity := item.Quantity - 1 + price := item.Price * uint64(quantity) + + if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&temp).Update("quantity", quantity).Error; err != nil { + return err + } + + if err := r.DB.Where("is_removed = ? ", false).Where("cart_item_id = ?", id).Model(&temp).Update("price", price).Error; err != nil { + return err + } + } + + return nil +} + +func (r *Cart_items_repository) UpdateStatus(id uint) error { + var item models.Cart_items + if err := r.DB.Where("is_removed = ?", false).Where("cart_item_id = ?", id).Model(&item).Update("status", "purchased").Error; err != nil { + return err + } + + return nil +} + +func (r *Cart_items_repository) Remove(id uint) error { + var cart_items models.Cart_items + if err := r.DB.Where("cart_item_id = ?", id).Model(&cart_items).Update("is_removed", true).Error; err != nil { + return err + } + + return nil +} diff --git a/repositories/Carts.go b/repositories/Carts.go new file mode 100644 index 0000000..f67e96f --- /dev/null +++ b/repositories/Carts.go @@ -0,0 +1,37 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Carts interface { + Create(*models.Carts) error + GetCart(id uint) (*models.Carts, error) +} + +type Carts_repository struct { + DB *gorm.DB +} + +func newCartsRepository(db *gorm.DB) Carts { + return &Carts_repository{DB: db} +} + +func (r *Carts_repository) Create(carts *models.Carts) error { + if err := r.DB.Create(&carts).Error; err != nil { + return err + } + + return nil +} + +func (r *Carts_repository) GetCart(id uint) (*models.Carts, error) { + var cart models.Carts + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).First(&cart).Error; err != nil { + return nil, err + } + + return &cart, nil +} diff --git a/repositories/Comment.go b/repositories/Comment.go new file mode 100644 index 0000000..f6693b6 --- /dev/null +++ b/repositories/Comment.go @@ -0,0 +1,67 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Comment interface { + Create(c *models.Comment) error + GetUserComments(id uint) ([]models.Comment, error) + GetProductComments(id uint) ([]models.Comment, error) + UpdateContent(id uint, content string) error + Delete(id uint) error +} + +type Comment_repository struct { + DB *gorm.DB +} + +func newCommentRepository(db *gorm.DB) Comment { + return &Comment_repository{DB: db} +} + +func (r *Comment_repository) Create(comment *models.Comment) error { + if err := r.DB.Create(&comment).Error; err != nil { + return err + } + + return nil +} + +func (r *Comment_repository) GetUserComments(id uint) ([]models.Comment, error) { + var comments []models.Comment + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&comments).Error; err != nil { + return nil, err + } + + return comments, nil +} + +func (r *Comment_repository) GetProductComments(id uint) ([]models.Comment, error) { + var comments []models.Comment + if err := r.DB.Where("is_removed = ?", false).Where("product_id = ?", id).Find(&comments).Error; err != nil { + return nil, err + } + + return comments, nil +} + +func (r *Comment_repository) UpdateContent(id uint, content string) error { + var comments models.Comment + if err := r.DB.Where("is_removed = ? ", false).Where("comment_id = ?", id).Model(comments).Update("content", content).Error; err != nil { + return err + } + + return nil +} + +func (r *Comment_repository) Delete(id uint) error { + var comments models.Comment + if err := r.DB.Where("comment_id = ?", id).Model(&comments).Update("is_removed", true).Error; err != nil { + return err + } + + return nil +} diff --git a/repositories/Order_product.go b/repositories/Order_product.go new file mode 100644 index 0000000..d62c39c --- /dev/null +++ b/repositories/Order_product.go @@ -0,0 +1,35 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Order_Product interface { + Create(op *models.Order_products) error + Delete(id uint) error +} + +type Order_Product_repository struct { + DB *gorm.DB +} + +func newOrderProductRepository(db *gorm.DB) Order_Product { + return &Order_Product_repository{DB: db} +} + +func (r *Order_Product_repository) Create(op *models.Order_products) error { + if err := r.DB.Create(&op).Error; err != nil { + return err + } + + return nil +} +func (r *Order_Product_repository) Delete(id uint) error { + var op models.Order_products + if err := r.DB.Where("order_products_id = ?", id).Model(&op).Update("is_removed", true).Error; err != nil { + return err + } + return nil +} diff --git a/repositories/Orders.go b/repositories/Orders.go new file mode 100644 index 0000000..ecbcafb --- /dev/null +++ b/repositories/Orders.go @@ -0,0 +1,57 @@ +package repositories + +import ( + "app/models" + "time" + + "gorm.io/gorm" +) + +type Orders interface { + Create(o *models.Order) error + GetOrders(id uint) ([]models.Order, error) + GetOrdersByDate(start time.Time, end time.Time) ([]models.Order, error) + Delete(id uint) error +} + +type Orders_repository struct { + DB *gorm.DB +} + +func newOrdersRepository(db *gorm.DB) Orders { + return &Orders_repository{DB: db} +} + +func (r *Orders_repository) Create(order *models.Order) error { + if err := r.DB.Create(&order).Error; err != nil { + return err + } + + return nil +} + +func (r *Orders_repository) GetOrders(id uint) ([]models.Order, error) { + var orders []models.Order + if err := r.DB.Where("is_removed = ?", false).Where("user_id").Find(&orders).Error; err != nil { + return nil, err + } + return orders, nil +} + +func (r *Orders_repository) GetOrdersByDate(start time.Time, end time.Time) ([]models.Order, error) { + var orders []models.Order + if err := r.DB.Where("is_removed = ?", false).Where("created_at BETWEEN ? and ?", start, end).Find(&orders).Error; err != nil { + return nil, err + } + + return orders, nil +} + +func (r *Orders_repository) Delete(id uint) error { + var order models.Order + if err := r.DB.Where("order_id = ?", id).Model(&order).Update("is_removed", true).Error; err != nil { + return err + } + + return nil +} diff --git a/repositories/Phone.go b/repositories/Phone.go new file mode 100644 index 0000000..44c7b62 --- /dev/null +++ b/repositories/Phone.go @@ -0,0 +1,67 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Phone interface { + Create(p *models.Phone) error + GetPhones(id uint) (*models.Phone, error) + UpdatePhoneNumber(number string, id uint) error + UpdateCellPhone(number string, id uint) error + Delete(id uint) error +} + +type Phone_repository struct { + DB *gorm.DB +} + +func newPhoneRepository(db *gorm.DB) Phone { + return &Phone_repository{DB: db} +} + +func (r *Phone_repository) Create(phone *models.Phone) error { + if err := r.DB.Create(&phone).Error; err != nil { + return err + } + + return nil +} + +func (r *Phone_repository) GetPhones(id uint) (*models.Phone, error) { + var phone models.Phone + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&phone).Error; err != nil { + return nil, err + } + + return &phone, nil +} + +func (r *Phone_repository) UpdatePhoneNumber(number string, id uint) error { + var phone models.Phone + if err := r.DB.Where("is_removed = ? ", false).Where("phone_id = ? ", id).Model(&phone).Update("phone_number", number).Error; err != nil { + return err + } + + return nil +} + +func (r *Phone_repository) UpdateCellPhone(number string, id uint) error { + var phone models.Phone + if err := r.DB.Where("is_removed = ? ", false).Where("phone_id = ? ", id).Model(&phone).Update("cell_phone_number", number).Error; err != nil { + return err + } + + return nil +} + +func (r *Phone_repository) Delete(id uint) error { + var phone models.Phone + if err := r.DB.Where("phone_id = ?", id).Model(&phone).Update("is_removed", true).Error; err != nil { + return err + } + + return nil +} diff --git a/repositories/Product.go b/repositories/Product.go new file mode 100644 index 0000000..260b227 --- /dev/null +++ b/repositories/Product.go @@ -0,0 +1,129 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Product interface { + Create(p *models.Product) error + GetByName(name string) ([]models.Product, error) + GetByID(id uint) (*models.Product, error) + GetByCategory(category string) ([]models.Product, error) + GetQuantity(id uint) (uint, error) + UpdateName(name string, id uint) error + UpdateDescription(content string, id uint) error + UpdateWarranty(name string, id uint) error + UpdateQuantity(quantity uint, id uint) error + UpdateCategory(category string, id uint) error + UpdatePrice(price uint64, id uint) error + Delete(id uint) error +} + +type Product_repository struct { + DB *gorm.DB +} + +func newProductRepository(db *gorm.DB) Product { + return &Product_repository{DB: db} +} + +func (r *Product_repository) Create(p *models.Product) error { + if err := r.DB.Create(&p).Error; err != nil { + return err + } + + return nil +} + +func (r *Product_repository) GetByName(name string) ([]models.Product, error) { + var product []models.Product + if err := r.DB.Where("is_removed = ?", false).Where("name = ? ", name).Find(&product).Error; err != nil { + return nil, err + } + + return product, nil +} + +func (r *Product_repository) GetByID(id uint) (*models.Product, error) { + var product models.Product + if err := r.DB.Where("is_removed = ?", false).Where("product_id = ? ", id).First(&product).Error; err != nil { + return nil, err + } + return &product, nil +} + +func (r *Product_repository) GetByCategory(category string) ([]models.Product, error) { + var product []models.Product + if err := r.DB.Where("is_removed = ?", false).Where("category = ?", category).Find(&product).Error; err != nil { + return nil, err + } + + return product, nil +} + +func (r *Product_repository) GetQuantity(id uint) (uint, error) { + var product models.Product + if err := r.DB.Where("is_removed = ?", false).Where("product_id = ?", id).First(&product).Error; err != nil { + return 0, err + } + + return product.Quantity, nil +} + +func (r *Product_repository) UpdateName(name string, id uint) error { + var product models.Product + if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("name", name).Error; err != nil { + return err + } + return nil +} + +func (r *Product_repository) UpdateDescription(content string, id uint) error { + var product models.Product + if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("description", content).Error; err != nil { + return err + } + return nil +} + +func (r *Product_repository) UpdateWarranty(name string, id uint) error { + var product models.Product + if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("warranty", name).Error; err != nil { + return err + } + return nil +} + +func (r *Product_repository) UpdateQuantity(quantity uint, id uint) error { + var product models.Product + if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("quantity", quantity).Error; err != nil { + return err + } + return nil +} + +func (r *Product_repository) UpdateCategory(category string, id uint) error { + var product models.Product + if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("category", category).Error; err != nil { + return err + } + return nil +} + +func (r *Product_repository) UpdatePrice(price uint64, id uint) error { + var product models.Product + if err := r.DB.Where("is_removed = ? ", false).Where("product_id = ?", id).Model(&product).Update("price", price).Error; err != nil { + return err + } + return nil +} + +func (r *Product_repository) Delete(id uint) error { + var product models.Product + if err := r.DB.Where("product_id = ?", id).Model(&product).Update("is_removed", true).Error; err != nil { + return err + } + return nil +} diff --git a/repositories/Specs.go b/repositories/Specs.go new file mode 100644 index 0000000..b6ef65f --- /dev/null +++ b/repositories/Specs.go @@ -0,0 +1,60 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Specs interface { + Create(s *models.Specs) error + GetSpecs(id uint) (*models.Specs, error) + UpdateType(newType string, id uint) error + UpdateValue(newValue string, id uint) error + Delete(id uint) error +} + +type Specs_repository struct { + DB *gorm.DB +} + +func newSpecsRepository(db *gorm.DB) Specs { + return &Specs_repository{DB: db} +} + +func (r *Specs_repository) Create(s *models.Specs) error { + if err := r.DB.Create(&s).Error; err != nil { + return err + } + return nil +} + +func (r *Specs_repository) GetSpecs(id uint) (*models.Specs, error) { + var specs models.Specs + if err := r.DB.Where("is_removed = ?", false).Where("product_id = ?", id).Find(&specs).Error; err != nil { + return nil, err + } + return &specs, nil +} +func (r *Specs_repository) UpdateType(newType string, id uint) error { + var specs models.Specs + if err := r.DB.Where("is_deleted = ?", false).Where("specs_id = ?", id).Model(&specs).Update("type", newType).Error; err != nil { + return err + } + return nil +} +func (r *Specs_repository) UpdateValue(newValue string, id uint) error { + var specs models.Specs + if err := r.DB.Where("is_deleted = ?", false).Where("specs_id = ?", id).Model(&specs).Update("value", newValue).Error; err != nil { + return err + } + return nil +} +func (r *Specs_repository) Delete(id uint) error { + var specs models.Specs + if err := r.DB.Where("specs_id = ?", id).Model(&specs).Update("is_removed", true).Error; err != nil { + return err + } + + return nil +} diff --git a/repositories/User.go b/repositories/User.go new file mode 100644 index 0000000..61a764f --- /dev/null +++ b/repositories/User.go @@ -0,0 +1,144 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type User interface { + Create(u *models.User) error + //GetAll()([]models.User,error) + GetByName(name string) ([]models.User, error) + GetByID(id uint) (*models.User, error) + UpdateUserName(name string, id uint) error + UpdateEmail(email string, id uint) error + UpdatePassword(password string, id uint) error + UpdateRole(newRole string, id uint) error + UpdateNationalCode(newCode string, id uint) error + UpdateBirthDay(newBirthDay string, id uint) error + UpdateFirstName(firstName string, id uint) error + UpdateLastName(lastName string, id uint) error + + Delete(id uint) error +} + +type User_repository struct { + DB *gorm.DB +} + +func newUserRepository(db *gorm.DB) User { + return &User_repository{DB: db} +} + +func (r *User_repository) Create(user *models.User) error { + + // if user.Password != "" { + // pw := user.Password + // hashpw, err := utils.HashPW(pw) + // if err != nil { + // return err + // } + // user.Password = hashpw + // } + if err := r.DB.Create(&user).Error; err != nil { + return err + } + + return nil +} + +// func (r *User_repository)GetAll()([]models.User,error){ +// var user []models.User +// if err := r.DB.Find(&user). +// } + +func (r *User_repository) GetByName(name string) ([]models.User, error) { + var user []models.User + if err := r.DB.Where("is_removed = ?", false).Where("username = ? ", name).Limit(12).Find(&user).Error; err != nil { + return nil, err + } + + return user, nil +} + +func (r *User_repository) GetByID(id uint) (*models.User, error) { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).First(&user).Error; err != nil { + return nil, err + } + + return &user, nil +} + +func (r *User_repository) UpdateUserName(name string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("username", name).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdateEmail(email string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("email", email).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdatePassword(password string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("password", password).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdateRole(newRole string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("role", newRole).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdateNationalCode(newCode string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("national_code", newCode).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdateBirthDay(newBirthDay string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("birth_day", newBirthDay).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdateFirstName(firstName string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("first_name", firstName).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) UpdateLastName(lastName string, id uint) error { + var user models.User + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ? ", id).Model(&user).Update("last_name", lastName).Error; err != nil { + return err + } + return nil +} + +func (r *User_repository) Delete(id uint) error { + var user models.User + if err := r.DB.Where("User_id = ?", id).Model(&user).Update("is_removed", true).Error; err != nil { + return err + } + return nil +} diff --git a/repositories/Wishlist.go b/repositories/Wishlist.go new file mode 100644 index 0000000..1925991 --- /dev/null +++ b/repositories/Wishlist.go @@ -0,0 +1,47 @@ +package repositories + +import ( + "app/models" + + "gorm.io/gorm" +) + +type Wishlist interface { + Create(w *models.Wishlist) error + GetList(id uint) ([]models.Wishlist, error) + Delete(id uint) error +} + +type Wishlist_repository struct { + DB *gorm.DB +} + +func newWishlistRepository(db *gorm.DB) Wishlist { + return &Wishlist_repository{DB: db} +} + +func (r *Wishlist_repository) Create(wishlist *models.Wishlist) error { + if err := r.DB.Create(&wishlist).Error; err != nil { + return err + } + + return nil +} + +func (r *Wishlist_repository) GetList(id uint) ([]models.Wishlist, error) { + var wishlist []models.Wishlist + if err := r.DB.Where("is_removed = ?", false).Where("user_id = ?", id).Find(&wishlist).Error; err != nil { + return nil, err + } + + return wishlist, nil +} + +func (r *Wishlist_repository) Delete(id uint) error { + var wishlist models.Wishlist + if err := r.DB.Where("wishlist_id = ?", id).Model(&wishlist).Update("is_removed", true).Error; err != nil { + return err + } + + return nil +} diff --git a/router/routers.go b/router/routers.go new file mode 100644 index 0000000..c6c3424 --- /dev/null +++ b/router/routers.go @@ -0,0 +1,123 @@ +package router + +import ( + "app/handlers" + "app/middlewares" + + login "app/services" + + "github.com/labstack/echo/v4" +) + +func UserRoutes(e *echo.Echo) { + users := e.Group("/users") + users.POST("/", handlers.RegisterUser) + users.GET("/usernames/:name", handlers.GetSameUserNames) + users.GET("/:id", handlers.GetUserByID) + users.PUT("/username/:id", handlers.UpdateUserName) + users.PUT("/email/:id", handlers.UpdateEmail) + users.PUT("/password/:id", handlers.UpdatePassword) + users.PUT("/role/:id", handlers.UpdateRole) + users.PUT("/nationalcode/:id", handlers.UpdateNationalCode) + users.PUT("/birthday/:id", handlers.UpdateBirthDay) + users.PUT("/firstname/:id", handlers.UpdateFirstName) + users.PUT("/lastname/:id", handlers.UpdateLastName) + users.PUT("/postcode/:id", handlers.UpdatePostCode) + users.DELETE("/:id", handlers.DeleteUser) +} + +// create new user ===> post : users/ +// get user by id ===> get : users/23 +// get users by name ===> get : users/nima +// update username ===> put : users/username send json +// update email ===> put : users/email send json +// update password ===> put : users/password send json +// update role ===> put : users/role send json +// update nationalCode ===> put : users/nationalcode send json +// update birthday ===> put : users/birthday send json +// update firstname ===> put : users/firstname send json +// update lastname ===> put : users/lastname send json +// update postcode ===> put : users/postcode send json +// delete user ===> delete : users/23 + +func ProductRoutes(e *echo.Echo) { + products := e.Group("/products") + products.POST("/", handlers.CreateProduct) + products.GET("/:name", handlers.GetProductByName) + products.GET("/:id", handlers.GetProductByID) + products.GET("/category/:name", handlers.GetProductByCategory) + products.PUT("/productname/:id", handlers.UpdateProductName) + products.PUT("/description/:id", handlers.UpdateDescription) + products.PUT("/warranty/:id", handlers.UpdateWarranty) + products.PUT("/quantity/:id", handlers.UpdateQuantity) + products.PUT("/category/:id", handlers.UpdateCategory) + products.PUT("/price/:id", handlers.UpdatePrice) + products.DELETE("/:id", handlers.DeleteProduct) +} + +func OrderRoutes(e *echo.Echo) { + orders := e.Group("/orders") + //orders.POST("/", handlers.CreateOrder) + orders.GET("/:id", handlers.GetUserOrders) + orders.DELETE("/:id", handlers.DeleteOrder) +} + +func AddressRoutes(e *echo.Echo) { + address := e.Group("/address") + address.POST("/", handlers.CreateAddress) + address.GET("/:id", handlers.GetUserAddresses) + address.PUT("/:id", handlers.UpdateAddress) + address.DELETE("/:id", handlers.DeleteAddress) +} + +func CommentRoutes(e *echo.Echo) { + comments := e.Group("/comments") + comments.POST("/", handlers.CreateComment) + comments.GET("/user/:id", handlers.GetUserComments) + comments.GET("/product/:id", handlers.GetProductComments) + comments.PUT("/:id", handlers.UpdateComment) + comments.DELETE("/:id", handlers.DeleteComment) +} + +func SpecsRoutes(e *echo.Echo) { + specs := e.Group("/specs") + specs.POST("/", handlers.CreateSpecs) + specs.GET("/:id", handlers.GetSpecs) + specs.PUT("/type/:id", handlers.UpdateType) + specs.PUT("/value/:id", handlers.UpdateValue) + specs.DELETE("/:id", handlers.DeleteSpecs) +} + +func PhoneRoutes(e *echo.Echo) { + phones := e.Group("/phones") + //phones.POST("/", handlers.CreatePhone) + phones.GET("/:id", handlers.GetUserPhoneNumbers) + phones.PUT("/phonenumber/:id", handlers.UpdatePhoneNumber) + phones.PUT("/cellphonenumber/:id", handlers.UpdateCellPhoneNumber) + phones.DELETE("/:id", handlers.DeletePhone) +} + +func WishlistRoutes(e *echo.Echo) { + wishlist := e.Group("/wishlist") + wishlist.POST("/", handlers.CreateWishlist) + wishlist.GET("/:id", handlers.GetWishlist) + wishlist.DELETE("/:id", handlers.DeleteWishlist) +} + +func CartRoutes(e *echo.Echo) { + cart := e.Group("/cart") + cart.POST("/", handlers.Create_cart_item) + cart.GET("/:id", handlers.GetCartItems) + cart.PUT("/:id", handlers.UpdateItemStatus) + cart.DELETE("/:id", handlers.Remove_cart_item) + +} + +func LoginLogout(e *echo.Echo) { + + e.POST("/login", login.LoginByEmail) + e.GET("/logout", login.Logout) + e.GET("/test", login.Test) + admin := e.Group("/admin") + admin.Use(middlewares.AdminOnly()) +} diff --git a/services/authentication.go b/services/authentication.go new file mode 100644 index 0000000..4f2c8d0 --- /dev/null +++ b/services/authentication.go @@ -0,0 +1,63 @@ +package services + +import ( + "app/utils" + + "net/http" + "time" + + "github.com/labstack/echo/v4" +) + +func LoginByEmail(c echo.Context) error { + + var info struct { + Email string `json:"email"` + Password string `json:"password"` + } + + if err := c.Bind(&info); err != nil { + return err + } + + if info.Email == "" || info.Password == "" { + return c.String(http.StatusUnauthorized, "pls check username and password") + } + + user, err := utils.GetUserByEmail(info.Email) + if err != nil { + return err + } + + checkpw, err := utils.Match(info.Password, info.Email) + if err != nil { + return err + } + + if !checkpw { + return c.String(http.StatusUnauthorized, "pls check username and password") + } else { + err = utils.CheckToken(c) + if err == echo.ErrUnauthorized { + utils.GenerateToken(c, *user) + } + return c.JSON(http.StatusOK, map[string]string{ + "message": "Login successful", + }) + } + +} + +func Logout(c echo.Context) error { + coockie := new(http.Cookie) + coockie.Name = "authorization" + coockie.Value = "" + // coockie.HttpOnly = true + // coockie.Secure = true + coockie.Expires = time.Now().Add(time.Hour * 24) + c.SetCookie(coockie) + + return c.JSON(http.StatusOK, map[string]string{ + "message": "Logout successful", + }) +} diff --git a/services/sms.go b/services/sms.go new file mode 100644 index 0000000..7b5bdc7 --- /dev/null +++ b/services/sms.go @@ -0,0 +1,21 @@ +package services + +import ( + "net/http" + + "github.com/kavenegar/kavenegar-go" + "github.com/labstack/echo/v4" +) + +func Test(c echo.Context) error { + api := kavenegar.New("55446E4B7564625A703969476D68315636464871325A52586D6C6E4C6C445A4F4E2B4D753637716A4E30593D") + + sender := "1000596446" + receptor := []string{"09356684212"} + + if _, err := api.Message.Send(sender, receptor, "hello-go", nil); err != nil { + panic(err) + } + + return c.String(http.StatusAccepted, "code sent") +} diff --git a/utils/checkEmail.go b/utils/checkEmail.go new file mode 100644 index 0000000..9d153b9 --- /dev/null +++ b/utils/checkEmail.go @@ -0,0 +1,26 @@ +package utils + +import ( + "app/database" + "app/models" + "errors" +) + +var ( + ErrEmailExists = errors.New("email already exists") +) + +func CheckEmail(email string) (bool, error) { + db := database.Db() + var user models.User + var count int64 + if err := db.Model(user).Where("email = ?", email).Count(&count).Error; err != nil { + return true, err + } + + if count > 0 { + return true, ErrEmailExists + } + + return false, nil +} diff --git a/utils/checkHash.go b/utils/checkHash.go new file mode 100644 index 0000000..ccd7186 --- /dev/null +++ b/utils/checkHash.go @@ -0,0 +1,87 @@ +package utils + +import ( + "crypto/subtle" + "encoding/base64" + "errors" + "fmt" + "strings" + + "golang.org/x/crypto/argon2" +) + +var ( + ErrInvalidHash = errors.New("the encoded hash is not in the correct format") + ErrIncompatibleVersion = errors.New("incompatible version of argon2") +) + +func Match(password string, email string) (bool, error) { + + user, err := GetUserByEmail(email) + if err != nil { + return false, err + } + + check, err := comparePasswordAndHash(password, user.Password) + if err != nil { + return false, err + } + + return check, nil +} + +func comparePasswordAndHash(password, encodedHash string) (match bool, err error) { + // Extract the parameters, salt and derived key from the encoded password + // hash. + p, salt, hash, err := decodeHash(encodedHash) + if err != nil { + return false, err + } + + // Derive the key from the other password using the same parameters. + otherHash := argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength) + + // Check that the contents of the hashed passwords are identical. Note + // that we are using the subtle.ConstantTimeCompare() function for this + // to help prevent timing attacks. + if subtle.ConstantTimeCompare(hash, otherHash) == 1 { + return true, nil + } + return false, nil +} + +func decodeHash(encodedHash string) (p *params, salt, hash []byte, err error) { + vals := strings.Split(encodedHash, "$") + if len(vals) != 6 { + return nil, nil, nil, ErrInvalidHash + } + + var version int + _, err = fmt.Sscanf(vals[2], "v=%d", &version) + if err != nil { + return nil, nil, nil, err + } + if version != argon2.Version { + return nil, nil, nil, ErrIncompatibleVersion + } + + p = ¶ms{} + _, err = fmt.Sscanf(vals[3], "m=%d,t=%d,p=%d", &p.memory, &p.iterations, &p.parallelism) + if err != nil { + return nil, nil, nil, err + } + + salt, err = base64.RawStdEncoding.Strict().DecodeString(vals[4]) + if err != nil { + return nil, nil, nil, err + } + p.saltLength = uint32(len(salt)) + + hash, err = base64.RawStdEncoding.Strict().DecodeString(vals[5]) + if err != nil { + return nil, nil, nil, err + } + p.keyLength = uint32(len(hash)) + + return p, salt, hash, nil +} diff --git a/utils/checkUser.go b/utils/checkUser.go new file mode 100644 index 0000000..cedaa47 --- /dev/null +++ b/utils/checkUser.go @@ -0,0 +1,36 @@ +package utils + +import ( + "app/database" + "app/models" + + "gorm.io/gorm" +) + +func CheckUserByJwt(jwtID uint) (uint, bool, error) { + db := database.Db() + var jwt models.Jwt + result := db.First(&jwt, jwtID) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return 0, false, nil + } + return 0, false, result.Error + } + + return jwt.User_id, true, nil +} + +func CheckUserByID(id uint) (bool, error) { + db := database.Db() + var jwt models.Jwt + result := db.Where("user_id = ?", id).First(&jwt) + if result.Error != nil { + if result.Error == gorm.ErrRecordNotFound { + return false, nil + } + return false, result.Error + } + + return true, nil +} diff --git a/utils/checkUserToken.go b/utils/checkUserToken.go new file mode 100644 index 0000000..01323c1 --- /dev/null +++ b/utils/checkUserToken.go @@ -0,0 +1,38 @@ +package utils + +import ( + "app/models" + "os" + + "github.com/golang-jwt/jwt/v5" + "github.com/joho/godotenv" + "github.com/labstack/echo/v4" +) + +func CheckToken(c echo.Context) error { + err := godotenv.Load("./config/.env") + if err != nil { + return err + } + secret := os.Getenv("SECRET") + + cookie, err := c.Cookie("authorization") + if err != nil { + return echo.ErrUnauthorized + } + + token, err := jwt.ParseWithClaims(cookie.Value, &models.JwtClaims{}, func(token *jwt.Token) (interface{}, error) { + // Provide the same key used for signing the token + return []byte(secret), nil + }) + if err != nil { + // Handle error, failed to parse the token + return echo.ErrUnauthorized + } + + if _, ok := token.Claims.(*models.JwtClaims); !ok || !token.Valid { + return echo.ErrUnauthorized + } + + return nil +} diff --git a/utils/generateToken.go b/utils/generateToken.go new file mode 100644 index 0000000..c73060e --- /dev/null +++ b/utils/generateToken.go @@ -0,0 +1,72 @@ +package utils + +import ( + "app/database" + "app/models" + "fmt" + "net/http" + "os" + "time" + + "github.com/golang-jwt/jwt/v5" + "github.com/joho/godotenv" + "github.com/labstack/echo/v4" +) + +func GenerateToken(c echo.Context, user models.User) (string, error) { + err := godotenv.Load("./config/.env") + if err != nil { + return "", err + } + secret := os.Getenv("SECRET") + db := database.Db() + + isExists, err := CheckUserByID(user.User_id) + if err != nil { + return "", err + } + fmt.Println(isExists) + + var jwtRecord models.Jwt + + if !isExists { + jwtRecord.User_id = user.User_id + err := db.Create(&jwtRecord).Error + if err != nil { + return "", err + } + } else { + if err = db.Where("user_id = ? ", user.User_id).First(&jwtRecord).Error; err != nil { + return "", err + } + } + + var tempJwt models.Jwt + + if err = db.Where("user_id = ?", jwtRecord.User_id).First(&tempJwt).Error; err != nil { + return "", err + } + + claims := &models.JwtClaims{ + Jwt_id: tempJwt.Jwt_id, + RegisteredClaims: jwt.RegisteredClaims{ + ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 168)), + }, + } + + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + sToken, err := token.SignedString([]byte(secret)) + if err != nil { + return "", err + } + + coockie := new(http.Cookie) + coockie.Name = "authorization" + coockie.Value = sToken + // coockie.HttpOnly = true + // coockie.Secure = true + coockie.Expires = time.Now().Add(time.Hour * 24) + c.SetCookie(coockie) + + return sToken, nil +} diff --git a/utils/getUserByEmail.go b/utils/getUserByEmail.go new file mode 100644 index 0000000..f304d54 --- /dev/null +++ b/utils/getUserByEmail.go @@ -0,0 +1,15 @@ +package utils + +import ( + "app/database" + "app/models" +) + +func GetUserByEmail(email string) (*models.User, error) { + user := new(models.User) + db := database.Db() + if err := db.Where("is_removed = ?", false).Where("email = ?", email).First(&user).Error; err != nil { + return nil, err + } + return user, nil +} diff --git a/utils/getUserByNumber.go b/utils/getUserByNumber.go new file mode 100644 index 0000000..3775c39 --- /dev/null +++ b/utils/getUserByNumber.go @@ -0,0 +1,17 @@ +package utils + +import ( + "app/database" + "app/models" +) + +func GetByPhoneNumber(number string) (*models.User, error) { + db := database.Db() + user := new(models.User) + if err := db.Where("is_removed = ?", false).Where("cell_phone_number = ?", number).First(&user).Error; err != nil { + return nil, err + } + + return user, nil + +} diff --git a/utils/hash.go b/utils/hash.go new file mode 100644 index 0000000..ef43b1a --- /dev/null +++ b/utils/hash.go @@ -0,0 +1,65 @@ +package utils + +import ( + "crypto/rand" + "encoding/base64" + "fmt" + + "golang.org/x/crypto/argon2" +) + +type params struct { + memory uint32 + iterations uint32 + parallelism uint8 + saltLength uint32 + keyLength uint32 +} + +func HashPW(password string) (string, error) { + // Establish the parameters to use for Argon2. + p := ¶ms{ + memory: 128 * 1024, + iterations: 3, + parallelism: 2, + saltLength: 16, + keyLength: 32, + } + + // Pass the plaintext password and parameters to our generateFromPassword + // helper function. + hash, err := generateFromPassword(password, p) + if err != nil { + return "", err + } + + return hash, nil +} + +func generateFromPassword(password string, p *params) (encodedHash string, err error) { + salt, err := generateRandomBytes(p.saltLength) + if err != nil { + return "", err + } + + hash := argon2.IDKey([]byte(password), salt, p.iterations, p.memory, p.parallelism, p.keyLength) + + // Base64 encode the salt and hashed password. + b64Salt := base64.RawStdEncoding.EncodeToString(salt) + b64Hash := base64.RawStdEncoding.EncodeToString(hash) + + // Return a string using the standard encoded hash representation. + encodedHash = fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", argon2.Version, p.memory, p.iterations, p.parallelism, b64Salt, b64Hash) + + return encodedHash, nil +} + +func generateRandomBytes(n uint32) ([]byte, error) { + b := make([]byte, n) + _, err := rand.Read(b) + if err != nil { + return nil, err + } + + return b, nil +} diff --git a/utils/parsetoken.go b/utils/parsetoken.go new file mode 100644 index 0000000..5591d0b --- /dev/null +++ b/utils/parsetoken.go @@ -0,0 +1,40 @@ +package utils + +import ( + "app/models" + "fmt" + "os" + "strconv" + + "github.com/golang-jwt/jwt/v5" + "github.com/joho/godotenv" +) + +func ParseToken(tokenString string) (string, error) { + err := godotenv.Load("./config/.env") + if err != nil { + return "", err + } + secret := os.Getenv("SECRET") + + claims := new(models.JwtClaims) + + token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { + // Provide the same key used for signing the token + return []byte(secret), nil + }) + if err != nil { + // Handle error, failed to parse the token + return "", err + } + + if !token.Valid { + // Handle invalid token + return "", fmt.Errorf("invalid token") + } + + fmt.Println(claims) + + return strconv.FormatUint(uint64(claims.Jwt_id), 10), nil + +} diff --git a/utils/productCount.go b/utils/productCount.go new file mode 100644 index 0000000..8bd8204 --- /dev/null +++ b/utils/productCount.go @@ -0,0 +1,19 @@ +package utils + +import ( + "app/database" + "app/models" +) + +func GetProductCount(id int64, cart_id uint) (uint, error) { + var count int64 + db := database.Db() + var product models.Cart_items + + // Query the count of products with the given name + if err := db.Model(&product).Where("product_id = ?", id).Where("is_removed = ?", false).Where("status = ? ", "pending").Where("cart_id = ?", cart_id).Count(&count).Error; err != nil { + return 0, err + } + + return uint(count), nil +}