Finished Prototype

This commit is contained in:
Hoernschen 2020-10-17 12:13:15 +02:00
parent ea54a27796
commit 6de476260d
30 changed files with 2189 additions and 0 deletions

19
entities/user/user.go Normal file
View file

@ -0,0 +1,19 @@
package user
type User struct {
Id string `json:"id,omitempty"`
Password string `json:"password,omitempty"`
Actor string `json:"actor,omitempty"`
Sessions []string `json:"sessions,omitempty"`
}
type RegisterRequest struct {
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
}
type RegisterResponse struct {
UserId string `json:"user_id,omitempty"`
Token string `json:"token,omitempty"`
Actor string `json:"actor,omitempty"`
}

View file

@ -0,0 +1,103 @@
package user
import (
"encoding/json"
"fmt"
"net/http"
"git.nutfactory.org/hoernschen/ActivityPub/entities/actor"
"git.nutfactory.org/hoernschen/ActivityPub/utils"
)
func New(id string, password string) (err error, newUser *User) {
err, hashedPassword := utils.Hash([]byte(password))
if err != nil {
return
}
newUser = &User{
Id: id,
Password: hashedPassword,
}
return
}
func RegisterHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
request := RegisterRequest{}
err := utils.CheckRequest(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(err); 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("Could not parse JSON: %s"); err != nil {
panic(err)
}
return
}
err, newUser := New(request.Username, request.Password)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(fmt.Sprintf("Error creating User Object: %s")); err != nil {
panic(err)
}
return
}
foundUser, err := ReadUser(newUser.Id)
if foundUser != nil || err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(fmt.Sprintf("Username already in use: %s", err)); err != nil {
panic(err)
}
return
}
newActor := actor.New(newUser.Id)
err = actor.CreateActor(newActor)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(fmt.Sprintf("Database Error Creating Actor: %s")); err != nil {
panic(err)
}
return
}
newUser.Actor = newActor.Id
err = CreateUser(newUser)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode("Database Error Creating User: %s"); err != nil {
panic(err)
}
return
}
err, token := utils.CreateToken()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode("Error Creating Token: %s"); err != nil {
panic(err)
}
return
}
err = CreateSession(newUser.Id, token)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode("Error Creating Session: %s"); err != nil {
panic(err)
}
return
}
response := RegisterResponse{
UserId: newUser.Id,
Token: token,
Actor: newActor.Id,
}
w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(response); err != nil {
panic(err)
}
}

View file

@ -0,0 +1,132 @@
package user
import (
"fmt"
"git.nutfactory.org/hoernschen/ActivityPub/utils/database"
)
func CreateUser(user *User) (err error) {
sqlStmt := fmt.Sprintf(`INSERT INTO user
(id, password, actor)
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.Password, user.Actor)
if err != nil {
tx.Rollback()
return
}
tx.Commit()
return
}
func CreateSession(userId string, token string) (err error) {
sqlStmt := fmt.Sprintf(`INSERT INTO session
(token, userId)
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(token, userId)
if err != nil {
tx.Rollback()
return
}
tx.Commit()
return
}
func ReadUser(id string) (foundUser *User, err error) {
queryStmt := fmt.Sprintf(`SELECT id, password, actor
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.Password, &foundUser.Actor)
if err != nil {
return
}
foundUser.Sessions, err = ReadSessionsForUser(foundUser.Id)
}
return
}
func ReadUserFromToken(token string) (foundUser *User, err error) {
queryStmt := fmt.Sprintf(`SELECT u.id, u.password, u.actor
FROM user as u
join session as s on u.id = s.userId
WHERE s.token = '%s'`, token)
rows, err := database.DB.Query(queryStmt)
if err != nil {
return
}
defer rows.Close()
if rows.Next() {
foundUser = &User{}
err = rows.Scan(&foundUser.Id, &foundUser.Password, &foundUser.Actor)
if err != nil {
return
}
foundUser.Sessions, err = ReadSessionsForUser(foundUser.Id)
}
return
}
func ReadSessionsForUser(userId string) (sessions []string, err error) {
queryStmt := fmt.Sprintf(`SELECT token
FROM session
WHERE userId = '%s'`, userId)
rows, err := database.DB.Query(queryStmt)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var session string
err = rows.Scan(&session)
if err != nil {
return
}
sessions = append(sessions, session)
}
return
}