From 7db9c374ccdcd11fd2f659e293898fa8d415ca5a Mon Sep 17 00:00:00 2001 From: hoernschen Date: Sun, 4 Oct 2020 14:22:52 +0200 Subject: [PATCH] Refactor Register Funktion --- entities/device/device.go | 7 +-- entities/device/deviceController.go | 27 ++++++++++- entities/user/userController.go | 72 ++++++++++++++++++++++------- utils/encryptionService.go | 42 +++++++++++++++++ utils/requestChecker.go | 2 +- 5 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 utils/encryptionService.go diff --git a/entities/device/device.go b/entities/device/device.go index 4b6f668..19631f3 100644 --- a/entities/device/device.go +++ b/entities/device/device.go @@ -1,7 +1,8 @@ package device type Device struct { - Id string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Keys map[string]*Key `json:"keys,omitempty"` + Id string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + AccessToken string `json:"accessToken,omitempty"` + Keys map[string]*Key `json:"keys,omitempty"` } diff --git a/entities/device/deviceController.go b/entities/device/deviceController.go index 779c740..2701a38 100644 --- a/entities/device/deviceController.go +++ b/entities/device/deviceController.go @@ -1,5 +1,30 @@ package device -func New() (device *Device) { +import "nutfactory.org/Matrix/utils" + +func New(name string) (err error, device *Device) { + err, id := utils.CreateUUID() + if err != nil { + return + } + err, token := utils.CreateToken() + if err != nil { + return + } + device = &Device{ + Id: id, + Name: name, + AccessToken: token, + Keys: make(map[string]*Key), + } + return +} + +func (device *Device) RenewAccesToken() (err error) { + err, token := utils.CreateToken() + if err != nil { + return + } + device.AccessToken = token return } diff --git a/entities/user/userController.go b/entities/user/userController.go index c60773a..1199026 100644 --- a/entities/user/userController.go +++ b/entities/user/userController.go @@ -2,13 +2,18 @@ package user import ( "encoding/json" + "log" "net/http" "nutfactory.org/Matrix/entities/device" "nutfactory.org/Matrix/utils" ) -func New(id string, name, string, password string, devices map[string]*device.Device) (newUser *User) { +func New(id string, name, string, password string, devices map[string]*device.Device) (err error, newUser *User) { + err, hashedPassword := utils.Hash([]byte(password)) + if err != nil { + return + } newUser = &User{ Id: id, Name: name, @@ -29,7 +34,7 @@ func CheckUsernameAvailability(w http.ResponseWriter, r *http.Request) { func Register(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") request := registerRequest{} - errResponse := utils.CheckRequest(r, request) + errResponse := utils.CheckRequest(r) if errResponse != nil { w.WriteHeader(http.StatusBadRequest) if err := json.NewEncoder(w).Encode(errResponse); err != nil { @@ -46,7 +51,7 @@ func Register(w http.ResponseWriter, r *http.Request) { } return } - errResponse = checkAuthData(&request.Auth) + errResponse = checkLoginType(request.Auth.LoginType) if errResponse != nil { w.WriteHeader(http.StatusBadRequest) if err := json.NewEncoder(w).Encode(errResponse); err != nil { @@ -78,6 +83,11 @@ func Register(w http.ResponseWriter, r *http.Request) { } userDevice, err := device.ReadDevice(request.DeviceId) if userDevice != nil { + err = userDevice.RenewAccesToken() + if err != nil { + log.Fatalf("Unable to renew AccesToken: %s", err) + return + } err = device.UpdateDevice(userDevice, newUser.Id) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -87,8 +97,11 @@ func Register(w http.ResponseWriter, r *http.Request) { return } } else { - // TODO: Use New Function - userDevice = &device.Device{} + err, userDevice = device.New(request.DeviceName) + if err != nil { + log.Fatalf("Unable to create device: %s", err) + return + } err = device.CreateDevice(userDevice, newUser.Id) if err != nil { w.WriteHeader(http.StatusBadRequest) @@ -99,9 +112,8 @@ func Register(w http.ResponseWriter, r *http.Request) { } } response := registerResponse{ - UserId: newUser.Id, - // TODO: Create Funktion for Token Generation - AccessToken: "TEST", + UserId: newUser.Id, + AccessToken: userDevice.AccessToken, DeviceId: userDevice.Id, } w.WriteHeader(http.StatusOK) @@ -111,6 +123,34 @@ func Register(w http.ResponseWriter, r *http.Request) { } func Login(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + request := loginRequest{} + errResponse := utils.CheckRequest(r) + if errResponse != nil { + w.WriteHeader(http.StatusBadRequest) + if err := json.NewEncoder(w).Encode(errResponse); err != nil { + panic(err) + } + return + } + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&request) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Could not parse JSON"}); err != nil { + panic(err) + } + return + } + errResponse = checkLoginType(request.LoginType) + if errResponse != nil { + w.WriteHeader(http.StatusBadRequest) + if err := json.NewEncoder(w).Encode(errResponse); err != nil { + panic(err) + } + return + } + w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) if err := json.NewEncoder(w).Encode("Test"); err != nil { @@ -128,16 +168,16 @@ func Logout(w http.ResponseWriter, r *http.Request) { func Deactivate(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) - if err := json.NewEncoder(w).Encode("Test"); err != nil { + w.WriteHeader(http.StatusBadRequest) + if err := json.NewEncoder(w).Encode("Not Implemented"); err != nil { panic(err) } } func ChangePassword(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) - if err := json.NewEncoder(w).Encode("Test"); err != nil { + w.WriteHeader(http.StatusBadRequest) + if err := json.NewEncoder(w).Encode("Not Implemented"); err != nil { panic(err) } } @@ -145,14 +185,14 @@ func ChangePassword(w http.ResponseWriter, r *http.Request) { //TODO: Check if necessary func Sync(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) - if err := json.NewEncoder(w).Encode("Test"); err != nil { + w.WriteHeader(http.StatusBadRequest) + if err := json.NewEncoder(w).Encode("Not Implemented"); err != nil { panic(err) } } -func checkAuthData(authData *authentificationData) (errResponse *utils.ErrorResponse) { - if authData.LoginType != "m.login.password" { +func checkLoginType(loginType string) (errResponse *utils.ErrorResponse) { + if loginType != "m.login.password" { errResponse = &utils.ErrorResponse{ErrorCode: "M_FORBIDDEN", ErrorMessage: "Unsupported Auth Type"} return } diff --git a/utils/encryptionService.go b/utils/encryptionService.go new file mode 100644 index 0000000..8b89ddf --- /dev/null +++ b/utils/encryptionService.go @@ -0,0 +1,42 @@ +package utils + +import ( + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "fmt" + "log" +) + +func CreateToken() (err error, token string) { + b := make([]byte, 8) + _, err = rand.Read(b) + if err != nil { + log.Fatal(err) + return + } + token = string(b) + return +} + +func CreateUUID() (err error, uuid string) { + b := make([]byte, 16) + _, err = rand.Read(b) + if err != nil { + log.Fatal(err) + return + } + uuid = fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]) + return +} + +func Hash(s []byte) (err error, hashString string) { + h := sha256.New() + _, err = h.Write(s) + if nil != err { + return + } + hash := h.Sum(nil) + hashString = base64.StdEncoding.EncodeToString(hash) + return +} diff --git a/utils/requestChecker.go b/utils/requestChecker.go index a808be7..7c3c530 100644 --- a/utils/requestChecker.go +++ b/utils/requestChecker.go @@ -12,7 +12,7 @@ type ErrorResponse struct { RetryTime int `json:"retry_after_ms,omitempty"` } -func CheckRequest(r *http.Request, request interface{}) (response *ErrorResponse) { +func CheckRequest(r *http.Request) (response *ErrorResponse) { if !strings.Contains(r.Header.Get("Content-Type"), "application/json") { response = &ErrorResponse{ErrorMessage: "Content Type not JSON"} }