Changes
This commit is contained in:
parent
7db9c374cc
commit
9eac960763
26 changed files with 3119 additions and 266 deletions
|
@ -11,6 +11,14 @@ type User struct {
|
|||
Devices map[string]*device.Device `json:"devices,omitempty"`
|
||||
}
|
||||
|
||||
type availableRequest struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
}
|
||||
|
||||
type availableResponse struct {
|
||||
Available bool `json:"available,omitempty"`
|
||||
}
|
||||
|
||||
type registerRequest struct {
|
||||
Auth authentificationData `json:"auth,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
|
@ -58,12 +66,6 @@ type changePasswordRequest struct {
|
|||
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"`
|
||||
|
|
|
@ -2,36 +2,72 @@ package user
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"nutfactory.org/Matrix/config"
|
||||
"nutfactory.org/Matrix/entities/device"
|
||||
"nutfactory.org/Matrix/utils"
|
||||
)
|
||||
|
||||
func New(id string, name, string, password string, devices map[string]*device.Device) (err error, newUser *User) {
|
||||
func New(username string, name string, password string) (err error, newUser *User) {
|
||||
err, hashedPassword := utils.Hash([]byte(password))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
id := generateUserId(username)
|
||||
newUser = &User{
|
||||
Id: id,
|
||||
Name: name,
|
||||
Password: password,
|
||||
Devices: devices,
|
||||
Password: hashedPassword,
|
||||
Devices: make(map[string]*device.Device),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CheckUsernameAvailability(w http.ResponseWriter, r *http.Request) {
|
||||
func CheckUsernameAvailabilityHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
request := availableRequest{}
|
||||
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: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
userId := generateUserId(request.Username)
|
||||
foundUser, err := ReadUser(userId)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
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
|
||||
}
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if err := json.NewEncoder(w).Encode("Test"); err != nil {
|
||||
if err := json.NewEncoder(w).Encode(availableResponse{Available: true}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Register(w http.ResponseWriter, r *http.Request) {
|
||||
func RegisterHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
request := registerRequest{}
|
||||
errResponse := utils.CheckRequest(r)
|
||||
|
@ -46,7 +82,7 @@ func Register(w http.ResponseWriter, r *http.Request) {
|
|||
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 {
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
|
@ -59,12 +95,7 @@ func Register(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
return
|
||||
}
|
||||
// TODO: Use New Function
|
||||
newUser := &User{
|
||||
Id: request.Username,
|
||||
Name: request.Username,
|
||||
Password: request.Password,
|
||||
}
|
||||
err, newUser := New(request.Username, request.Username, request.Password)
|
||||
foundUser, err := ReadUser(newUser.Id)
|
||||
if foundUser != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
|
@ -76,40 +107,18 @@ func Register(w http.ResponseWriter, r *http.Request) {
|
|||
err = CreateUser(newUser)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Database Error"}); err != nil {
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
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)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Database Error"}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
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)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Database Error"}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
userDevice, errResponse := createUserDevice(request.DeviceId, request.DeviceName, newUser.Id)
|
||||
if errResponse != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(errResponse); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
response := registerResponse{
|
||||
UserId: newUser.Id,
|
||||
|
@ -122,7 +131,7 @@ func Register(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func Login(w http.ResponseWriter, r *http.Request) {
|
||||
func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
request := loginRequest{}
|
||||
errResponse := utils.CheckRequest(r)
|
||||
|
@ -137,7 +146,7 @@ func Login(w http.ResponseWriter, r *http.Request) {
|
|||
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 {
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Could not parse JSON: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
|
@ -150,40 +159,91 @@ func Login(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
if request.Identifier.IdentifierType != "m.id.user" && request.Identifier.User == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: "Username missing"}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
userId := generateUserId(request.Identifier.User)
|
||||
foundUser, err := ReadUser(userId)
|
||||
if err != nil || foundUser == nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorCode: "M_FORBIDDEN"}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
err, hashedPassword := utils.Hash([]byte(request.Password))
|
||||
if err != nil || foundUser.Password != hashedPassword {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorCode: "M_FORBIDDEN"}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
userDevice, errResponse := createUserDevice(request.DeviceId, request.DeviceName, request.Identifier.User)
|
||||
if errResponse != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(errResponse); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
response := loginResponse{
|
||||
UserId: foundUser.Id,
|
||||
AccessToken: userDevice.AccessToken,
|
||||
DeviceId: userDevice.Id,
|
||||
}
|
||||
response.DiscoveryInfo.Homeserver.BaseUrl = config.Homeserver
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
if err := json.NewEncoder(w).Encode("Test"); err != nil {
|
||||
if err := json.NewEncoder(w).Encode(response); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func Logout(w http.ResponseWriter, r *http.Request) {
|
||||
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
errResponse := utils.CheckRequest(r)
|
||||
if errResponse != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(errResponse); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
accessToken, errResponse := utils.GetAccessToken(r)
|
||||
if errResponse != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(errResponse); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
foundDevice, err := device.ReadDeviceFromAccessToken(accessToken)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
foundDevice.AccessToken = ""
|
||||
err = device.UpdateDevice(foundDevice)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode(utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
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.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.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode("Not Implemented"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Check if necessary
|
||||
func Sync(w http.ResponseWriter, r *http.Request) {
|
||||
func SyncHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
if err := json.NewEncoder(w).Encode("Not Implemented"); err != nil {
|
||||
|
@ -193,8 +253,47 @@ func Sync(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
func checkLoginType(loginType string) (errResponse *utils.ErrorResponse) {
|
||||
if loginType != "m.login.password" {
|
||||
errResponse = &utils.ErrorResponse{ErrorCode: "M_FORBIDDEN", ErrorMessage: "Unsupported Auth Type"}
|
||||
errResponse = &utils.ErrorResponse{ErrorCode: "M_UNKNOWN", ErrorMessage: "Bad login type."}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func generateUserId(username string) string {
|
||||
return fmt.Sprintf("@%s:%s", username, config.Homeserver)
|
||||
}
|
||||
|
||||
func createUserDevice(id string, name string, userId string) (userDevice *device.Device, errResponse *utils.ErrorResponse) {
|
||||
userDevice, err := device.ReadDevice(id)
|
||||
if err != nil {
|
||||
errResponse = &utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}
|
||||
return
|
||||
}
|
||||
if userDevice != nil {
|
||||
err = userDevice.RenewAccesToken()
|
||||
if name != "" {
|
||||
userDevice.Name = name
|
||||
}
|
||||
if err != nil {
|
||||
errResponse = &utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Unable to renew AccesToken: %s", err)}
|
||||
return
|
||||
}
|
||||
err = device.UpdateDevice(userDevice)
|
||||
if err != nil {
|
||||
errResponse = &utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}
|
||||
return
|
||||
}
|
||||
} else {
|
||||
err, userDevice = device.New(name)
|
||||
if err != nil {
|
||||
errResponse = &utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Unable to create device: %s", err)}
|
||||
return
|
||||
}
|
||||
err = device.CreateDevice(userDevice, userId)
|
||||
if err != nil {
|
||||
errResponse = &utils.ErrorResponse{ErrorMessage: fmt.Sprintf("Database Error: %s", err)}
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -56,6 +56,31 @@ func ReadUser(id string) (foundUser *User, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func ReadUserFromAccessToken(accessToken string) (foundUser *User, err error) {
|
||||
queryStmt := fmt.Sprintf(`SELECT u.id, u.name, u.password
|
||||
FROM user as u
|
||||
join device as d on u.id = d.userId
|
||||
WHERE d.accessToken = '%s'`, accessToken)
|
||||
|
||||
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 = ?,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue