Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// define package name
package controllers
// import library
import(
"time"
"context"
"github.com/gin-gonic/gin"
"github.com/Debzou/REST-API-GO/internal/models"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/bson"
"log"
"golang.org/x/crypto/bcrypt"
"strings"
"net/http"
)
// DATABASE INSTANCE
var collection *mongo.Collection
// define the collection
func UserCollection(c *mongo.Database) {
collection = c.Collection("users")
}
func CreateUser(c *gin.Context) {
var json models.User
c.Bind(&json) // This will infer what binder to use depending on the content-type header.
// gather username and transform to lower case
username := strings.ToLower(json.Username)
//hash password
hashpassword, err := HashPassword(json.Password)
if err != nil {
log.Printf("Error, Reason: %v\n", err)
}
// create with models an user
user := models.User{Username: username,
Password: hashpassword,
Status: "normal_user"}
// check if username exist
if (isExist(username)){
// username already exist
c.JSON(http.StatusOK, gin.H{"message": "User already exist"})
return
}else{
// post user in mongodb (username no exist)
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
collection.InsertOne(ctx, user)
// display message & httpstatus
c.JSON(http.StatusOK, gin.H{"message": "User is created"})
return
}
}
// return true if authenticate is true and the status value
func AuthUser(username string,password string) (bool,string){
// init user structure
user := models.User{}
// define the context
ctx, cancel:= context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() // releases resources if slowOperation completes before timeout elapses
// check if user exist
err := collection.FindOne(ctx, bson.M{"username": username}).Decode(&user)
if err != nil {
log.Printf("Error, Reason: %v\n", err)
return false,"no_status"
}
// check the password
if !(CheckPasswordHash(password, user.Password)) {
log.Printf("incorrect password")
return false,"incorrect_pass"
}
return true,user.Status
}
func isExist(username string) bool{
// init user structure
user := models.User{}
// define the context
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() // releases resources if slowOperation completes before timeout elapses
// find an user
err := collection.FindOne(ctx,bson.M{"username": username}).Decode(&user)
// the user exist
if err != nil {
log.Printf("Error, Reason: %v\n", err)
return false
// the user not exist
}else{
return true
}
}
// hash password
func HashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(bytes), err
}
// compare hash password with password
func CheckPasswordHash(password, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
return err == nil
}