Refactor Database Connector, Implement Register

This commit is contained in:
hoernschen 2020-10-03 14:22:29 +02:00
parent 0cc882cff0
commit c79d1f86e4
18 changed files with 1495 additions and 1234 deletions

View file

@ -10,3 +10,83 @@ type User struct {
Password string `json:"password,omitempty"`
Devices map[string]*device.Device `json:"devices,omitempty"`
}
type registerRequest struct {
Auth authentificationData `json:"auth,omitempty"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
DeviceId string `json:"device_id,omitempty"`
DeviceName string `json:"initial_device_display_name,omitempty"`
InhibitLogin bool `json:"inhibit_login,omitempty"`
}
type registerResponse struct {
UserId string `json:"user_id,omitempty"`
AccessToken string `json:"access_token,omitempty"`
HomeServer string `json:"home_server,omitempty"`
DeviceId string `json:"device_id,omitempty"`
}
type loginRequest struct {
LoginType string `json:"type,omitempty"`
Identifier identifier `json:"identifier,omitempty"`
Password string `json:"password,omitempty"`
Token string `json:"token,omitempty"`
DeviceId string `json:"device_id,omitempty"`
DeviceName string `json:"initial_device_display_name,omitempty"`
}
type loginResponse struct {
UserId string `json:"user_id,omitempty"`
AccessToken string `json:"access_token,omitempty"`
DeviceId string `json:"device_id,omitempty"`
DiscoveryInfo discoveryInformation `json:"well_known,omitempty"`
}
type deaktivateUserRequest struct {
Auth authentificationData `json:"auth,omitempty"`
IdentityServer string `json:"id_server,omitempty"`
}
type deaktivateUserResponse struct {
Unbind3PIDS string `json:"id_server_unbind_result,omitempty"` // success or no-support
}
type changePasswordRequest struct {
NewPassword string
LogoutDevices bool
Auth authentificationData
}
type errorResponse struct {
ErrorCode string `json:"errcode,omitempty"`
ErrorMessage string `json:"error,omitempty"`
RetryTime int `json:"retry_after_ms,omitempty"`
}
type identifier struct {
IdentifierType string `json:"type,omitempty"`
User string `json:"user,omitempty"`
Medium string `json:"medium,omitempty"`
Address string `json:"address,omitempty"`
Country string `json:"country,omitempty"`
Phone string `json:"phone,omitempty"`
}
type authentificationData struct {
LoginType string `json:"type,omitempty"`
Session string `json:"session,omitempty"`
}
type discoveryInformation struct {
Homeserver homeserverInformation `json:"m.homeserver,omitempty"`
IdentityServer identityServerInformation `json:"m.identity_server,omitempty"`
}
type homeserverInformation struct {
BaseUrl string `json:"base_url,omitempty"`
}
type identityServerInformation struct {
BaseUrl string `json:"base_url,omitempty"`
}

View file

@ -1,5 +1,160 @@
package user
func New() (user *User) {
import (
"encoding/json"
"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) {
newUser = &User{
Id: id,
Name: name,
Password: password,
Devices: devices,
}
return
}
func CheckUsernameAvailability(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 {
panic(err)
}
}
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)
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 = checkAuthData(&request.Auth)
if errResponse != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(errResponse); err != nil {
panic(err)
}
return
}
// TODO: Use New Function
newUser := &User{
Id: request.Username,
Name: request.Username,
Password: request.Password,
}
foundUser, err := ReadUser(newUser.Id)
if foundUser != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorCode: "M_USER_IN_USE", ErrorMessage: "Username already in use"}); err != nil {
panic(err)
}
return
}
err = CreateUser(newUser)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Database Error"}); err != nil {
panic(err)
}
return
}
userDevice, err := device.ReadDevice(request.DeviceId)
if userDevice != nil {
err = device.UpdateDevice(userDevice, newUser.Id)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Database Error"}); err != nil {
panic(err)
}
return
}
} else {
// TODO: Use New Function
userDevice = &device.Device{}
err = device.CreateDevice(userDevice, newUser.Id)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Database Error"}); err != nil {
panic(err)
}
return
}
}
response := registerResponse{
UserId: newUser.Id,
// TODO: Create Funktion for Token Generation
AccessToken: "TEST",
DeviceId: userDevice.Id,
}
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(response); err != nil {
panic(err)
}
}
func Login(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 {
panic(err)
}
}
func Logout(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 {
panic(err)
}
}
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 {
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 {
panic(err)
}
}
//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 {
panic(err)
}
}
func checkAuthData(authData *authentificationData) (errResponse *utils.ErrorResponse) {
if authData.LoginType != "m.login.password" {
errResponse = &utils.ErrorResponse{ErrorCode: "M_FORBIDDEN", ErrorMessage: "Unsupported Auth Type"}
return
}
return
}

View file

@ -0,0 +1,101 @@
package user
import (
"fmt"
"nutfactory.org/Matrix/entities/device"
"nutfactory.org/Matrix/utils/database"
)
func CreateUser(user *User) (err error) {
sqlStmt := fmt.Sprintf(`INSERT INTO user
(id, name, password)
VALUES
(?, ?, ?)`)
tx, err := database.DB.Begin()
if err != nil {
return
}
stmt, err := tx.Prepare(sqlStmt)
if err != nil {
return
}
defer stmt.Close()
_, err = stmt.Exec(user.Id, user.Name, user.Password)
if err != nil {
return
}
tx.Commit()
return
}
func ReadUser(id string) (foundUser *User, err error) {
queryStmt := fmt.Sprintf(`SELECT id, name, password
FROM user
WHERE id = '%s'`, id)
rows, err := database.DB.Query(queryStmt)
if err != nil {
return
}
defer rows.Close()
if rows.Next() {
foundUser = &User{}
err = rows.Scan(&foundUser.Id, &foundUser.Name, &foundUser.Password)
if err != nil {
return
}
foundUser.Devices, err = device.ReadDevicesForUser(foundUser.Id)
}
return
}
func UpdateUser(user *User) (err error) {
sqlStmt := fmt.Sprintf(`UPDATE user SET
name = ?,
password = ?
WHERE id = ?`)
tx, err := database.DB.Begin()
if err != nil {
return
}
stmt, err := tx.Prepare(sqlStmt)
if err != nil {
return
}
defer stmt.Close()
_, err = stmt.Exec(user.Name, user.Password, user.Id)
if err != nil {
return
}
tx.Commit()
return
}
func DeleteUser(id string) (err error) {
queryStmt := fmt.Sprintf(`DELETE FROM user
WHERE id = '%s'`, id)
tx, err := database.DB.Begin()
if err != nil {
return
}
_, err = database.DB.Exec(queryStmt)
if err != nil {
return
}
tx.Commit()
return
}