Skip to content

Commit

Permalink
implement user DB
Browse files Browse the repository at this point in the history
  • Loading branch information
jbsv committed Dec 27, 2023
1 parent ac3a1fd commit 7dff5c5
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 28 deletions.
8 changes: 4 additions & 4 deletions server/registration/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import "go.dedis.ch/hbt/server/registration/registry"
// Database defines a generic CRUD interface to the database
type Database interface {
// Create creates a new document in the database
Create(registry.RegistrationData) (registry.DocId, error)
Create(registry.RegistrationData) (*registry.RegistrationId, error)

// Read retrieves a document from the database
// it takes the document ID as an argument
// and returns the document
Read(registry.DocId) (*registry.RegistrationData, error)
Read(registry.RegistrationId, []byte) (*registry.RegistrationData, error)

// Update updates a document in the database
// it takes the document ID and the updated document as an argument
Update(registry.DocId, *registry.RegistrationData) error
Update(registry.RegistrationId, []byte, *registry.RegistrationData) error

// DeleteDocument deletes a document from the database
// it takes the document ID as an argument
Delete(registry.DocId) error
Delete(registry.RegistrationId, []byte) error

// Disconnect disconnects from the database
Disconnect() error
Expand Down
15 changes: 11 additions & 4 deletions server/registration/database/mongodb/admindb.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,29 @@ func NewAdminDbAccess() *AdminDbAccess {
}

// Create creates a new document in the DB
func (a AdminDbAccess) Create(doc registry.RegistrationData) (registry.DocId, error) {
func (a AdminDbAccess) Create(doc registry.RegistrationData) (*registry.RegistrationId, error) {
return nil, errors.New("admin cannot create user documents")
}

// Read reads a document from the DB
func (a AdminDbAccess) Read(docId registry.DocId) (*registry.RegistrationData, error) {
func (a AdminDbAccess) Read(docId registry.RegistrationId, hash []byte) (
*registry.RegistrationData,
error,
) {
return nil, nil
}

// Update updates a document in the DB
func (a AdminDbAccess) Update(docId registry.DocId, reg *registry.RegistrationData) error {
func (a AdminDbAccess) Update(
docId registry.RegistrationId,
hash []byte,
reg *registry.RegistrationData,
) error {
return nil
}

// Delete updates a document in the DB
func (a AdminDbAccess) Delete(docId registry.DocId) error {
func (a AdminDbAccess) Delete(docId registry.RegistrationId, hash []byte) error {
return nil
}

Expand Down
11 changes: 11 additions & 0 deletions server/registration/database/mongodb/dbtypes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package mongodb

// Document is a database struct for the registration service
type Document struct {
Name string `bson:"name"`
Passport string `bson:"passport"`
Role uint `bson:"role"`
Picture []byte `bson:"picture"`
Hash []byte `bson:"hash"`
Registered bool `bson:"registered"`
}
111 changes: 105 additions & 6 deletions server/registration/database/mongodb/userdb.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mongodb

import (
"bytes"
"context"
"errors"

Expand Down Expand Up @@ -36,7 +37,16 @@ func NewUserDbAccess() database.Database {
}

// Create creates a new document in the DB
func (u UserDbAccess) Create(doc registry.RegistrationData) (registry.DocId, error) {
func (u UserDbAccess) Create(data registry.RegistrationData) (*registry.RegistrationId, error) {
doc := Document{
Name: data.Name,
Passport: data.Passport,
Role: data.Role,
Picture: data.Picture,
Hash: data.Hash,
Registered: false,
}

result, err := u.client.Database("registration").Collection("documents").InsertOne(context.Background(),
doc)

Expand All @@ -45,24 +55,113 @@ func (u UserDbAccess) Create(doc registry.RegistrationData) (registry.DocId, err
}

if oid, ok := result.InsertedID.(primitive.ObjectID); ok {
return oid.MarshalJSON()
id, err := oid.MarshalJSON()
if err != nil {
return nil, err
}

registrationId := registry.RegistrationId{
Id: id,
}

return &registrationId, nil

}

return nil, errors.New("could not marshal object id")
}

// Read reads a document from the DB
func (u UserDbAccess) Read(docId registry.DocId) (*registry.RegistrationData, error) {
return nil, nil
// it is used to get the registered value of a document
func (u UserDbAccess) Read(docId registry.RegistrationId, hash []byte) (
*registry.RegistrationData,
error,
) {
var doc Document

err := u.client.Database("registration").Collection("documents").FindOne(context.Background(),
docId).Decode(&doc)

if err != nil {
return nil, err
}

if hash != nil {
if !bytes.Equal(hash, doc.Hash) {
return nil, errors.New("hashes do not match")
}
}

data := registry.RegistrationData{
Name: doc.Name,
Passport: doc.Passport,
Role: doc.Role,
Registered: doc.Registered,
}

return &data, nil
}

// Update updates a document in the DB
func (u UserDbAccess) Update(docId registry.DocId, reg *registry.RegistrationData) error {
func (u UserDbAccess) Update(
docId registry.RegistrationId,
hash []byte,
reg *registry.RegistrationData,
) error {
var doc Document

err := u.client.Database("registration").Collection("documents").FindOne(context.Background(),
docId).Decode(&doc)
if err != nil {
return err
}

if !bytes.Equal(hash, doc.Hash) {
return errors.New("hashes do not match")
}

reg.Name = doc.Name
reg.Passport = doc.Passport
reg.Role = doc.Role
reg.Picture = doc.Picture
reg.Registered = false

result, err := u.client.Database("registration").Collection("documents").UpdateOne(context.Background(),
docId, reg)
if err != nil {
return err
}

if result.ModifiedCount != 1 {
return errors.New("could not update document")
}

return nil
}

// Delete updates a document in the DB
func (u UserDbAccess) Delete(docId registry.DocId) error {
func (u UserDbAccess) Delete(docId registry.RegistrationId, hash []byte) error {
var doc Document

err := u.client.Database("registration").Collection("documents").FindOne(context.Background(),
docId).Decode(&doc)
if err != nil {
return err
}

if !bytes.Equal(hash, doc.Hash) {
return errors.New("hashes do not match")
}

result, err := u.client.Database("registration").Collection("documents").DeleteOne(context.Background(),
docId)
if err != nil {
return err
}
if result.DeletedCount != 1 {
return errors.New("could not delete document")
}

return nil
}

Expand Down
35 changes: 33 additions & 2 deletions server/registration/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,44 @@ type application struct {
AdminRouter *mux.Router
}

// newApp creates a new application instance
// it creates the user and admin router
// and registers the handlers
// the routes used are pretty simple:
// - /document for the user
// - /admin/document for the admin
// to create a new document, the user sends a POST request to /document
// with the following form data:
// - name: string
// - passport: string
// - role: uint
// - image: file
// the response is a json string containing the document id
// to get a document, the user sends a GET request to /document
// with the following query parameter:
// - id: string
// to delete a document, the user sends a DELETE request to /document
// with the following query parameter:
// - id: string
// to get a document, the admin sends a GET request to /admin/document
// with the following query parameter:
// - id: string
// to update a document, the admin sends a PUT request to /admin/document
// with the following query parameter:
// - id: string
// and the following form data:
// - name: string
// - passport: string
// - role: uint
// - registered: bool
func newApp() *application {
userRouter := mux.NewRouter()
userRouter.HandleFunc("/document", user.CreateDocument).Methods("POST")
userRouter.HandleFunc("/document/{id}", user.GetDocument).Methods("GET")
userRouter.HandleFunc("/document", user.GetDocument).Methods("GET")
userRouter.HandleFunc("/document", user.DeleteDocument).Methods("DELETE")

adminRouter := mux.NewRouter()
adminRouter.HandleFunc("/admin/document/{id}", admin.GetDocument).Methods("GET")
adminRouter.HandleFunc("/admin/document", admin.GetDocument).Methods("GET")
adminRouter.HandleFunc("/admin/document/{id}", admin.UpdateDocument).Methods("PUT")
adminRouter.HandleFunc("/admin/document/{id}", admin.DeleteDocument).Methods("DELETE")

Expand Down
Binary file added server/registration/registration
Binary file not shown.
10 changes: 1 addition & 9 deletions server/registration/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,11 @@ type RegistrationData struct {
Passport string `json:"passport"`
Role uint `json:"role"`
Picture []byte `json:"picture"`
Hash []byte `json:"hash"`
Registered bool `json:"registered"`
}

// RegistrationId contains the reference to the document in the database
type RegistrationId struct {
Id DocId `json:"doc_id"`
}

// Document is a database struct for the registration service
type Document struct {
Name string `bson:"name"`
Passport string `bson:"passport"`
Role uint `bson:"role"`
Picture []byte `bson:"picture"`
Registered bool `bson:"registered"`
}
61 changes: 58 additions & 3 deletions server/registration/registry/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,85 @@ func CreateDocument(w http.ResponseWriter, r *http.Request) {
log.Fatal(err)
}
picture, fileHeader, err := r.FormFile("image")
if err != nil {
log.Println(err)
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
return
}

fmt.Println(fileHeader)

picData := make([]byte, fileHeader.Size)
picture.Read(picData)

hash := r.FormValue("hash")

regData := registry.RegistrationData{
Name: name,
Passport: passport,
Role: uint(role),
Picture: picData,
Hash: []byte(hash),
}

docId, err := userDb.Create(regData)

if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

response := registry.RegistrationId{Id: docId}

json.NewEncoder(w).Encode(response)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(docId)
fmt.Println(docId)
}

// GetDocument translates the http request to get a document from the database
func GetDocument(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("missing id"))
}

hash := r.FormValue("hash")

regId := registry.RegistrationId{
Id: []byte(id),
}

data, err := userDb.Read(regId, []byte(hash))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

json.NewEncoder(w).Encode(data)
}

// DeleteDocument translates the http request to delete a document in the database
func DeleteDocument(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("missing id"))
}

hash := r.FormValue("hash")

regId := registry.RegistrationId{
Id: []byte(id),
}

err := userDb.Delete(regId, []byte(hash))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
return
}

w.WriteHeader(http.StatusOK)
}

0 comments on commit 7dff5c5

Please sign in to comment.