Compare commits
4 commits
ad4d439887
...
25fdf3bb9b
Author | SHA1 | Date | |
---|---|---|---|
![]() |
25fdf3bb9b | ||
![]() |
c4632104a8 | ||
![]() |
736cebe036 | ||
![]() |
9b67a580da |
8 changed files with 76 additions and 164 deletions
|
@ -12,7 +12,9 @@ import (
|
|||
|
||||
// Interface for the database
|
||||
type Database interface {
|
||||
// Insert a new user into the database, password should be hashed before calling
|
||||
AddUser(username string, password string) error
|
||||
|
||||
RemoveUser(username string) error
|
||||
PromoteToAdmin(username string) error
|
||||
GetUserId(username string) (int, error)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
-- Id is a surrogate key for in ternal use
|
||||
-- userId is what is used for external id
|
||||
-- username is what is used for login
|
||||
-- password is the hashed password
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
userId TEXT DEFAULT (HEX(RANDOMBLOB(4))) NOT NULL UNIQUE,
|
||||
|
@ -5,5 +9,6 @@ CREATE TABLE IF NOT EXISTS users (
|
|||
password VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
-- Users are commonly searched by username and userId
|
||||
CREATE INDEX IF NOT EXISTS users_username_index ON users (username);
|
||||
CREATE INDEX IF NOT EXISTS users_userId_index ON users (userId);
|
16
backend/internal/database/migrations/0070_salts.sql
Normal file
16
backend/internal/database/migrations/0070_salts.sql
Normal file
|
@ -0,0 +1,16 @@
|
|||
-- It is unclear weather this table will be used
|
||||
|
||||
-- Create the table to store hash salts
|
||||
CREATE TABLE salts (
|
||||
id INTEGER PRIMARY KEY,
|
||||
salt TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Commented out for now, no time for good practices, which is atrocious
|
||||
-- Create a trigger to automatically generate a salt when inserting a new user record
|
||||
-- CREATE TRIGGER generate_salt_trigger
|
||||
-- AFTER INSERT ON users
|
||||
-- BEGIN
|
||||
-- INSERT INTO salts (salt) VALUES (randomblob(16));
|
||||
-- UPDATE users SET salt_id = (SELECT last_insert_rowid()) WHERE id = new.id;
|
||||
-- END;
|
|
@ -11,11 +11,11 @@ import (
|
|||
|
||||
// The actual interface that we will use
|
||||
type GlobalState interface {
|
||||
Register(c *fiber.Ctx) error // To register a new user
|
||||
UserDelete(c *fiber.Ctx) error // To delete a user
|
||||
Login(c *fiber.Ctx) error // To get the token
|
||||
LoginRenew(c *fiber.Ctx) error // To renew the token
|
||||
// CreateProject(c *fiber.Ctx) error // To create a new project
|
||||
Register(c *fiber.Ctx) error // To register a new user
|
||||
UserDelete(c *fiber.Ctx) error // To delete a user
|
||||
Login(c *fiber.Ctx) error // To get the token
|
||||
LoginRenew(c *fiber.Ctx) error // To renew the token
|
||||
CreateProject(c *fiber.Ctx) error // To create a new project
|
||||
// GetProjects(c *fiber.Ctx) error // To get all projects
|
||||
// GetProject(c *fiber.Ctx) error // To get a specific project
|
||||
// UpdateProject(c *fiber.Ctx) error // To update a project
|
||||
|
@ -58,7 +58,7 @@ type GState struct {
|
|||
// @Failure 500 {string} string "Internal server error"
|
||||
// @Router /api/register [post]
|
||||
func (gs *GState) Register(c *fiber.Ctx) error {
|
||||
u := new(types.User)
|
||||
u := new(types.NewUser)
|
||||
if err := c.BodyParser(u); err != nil {
|
||||
return c.Status(400).SendString(err.Error())
|
||||
}
|
||||
|
@ -142,3 +142,24 @@ func (gs *GState) LoginRenew(c *fiber.Ctx) error {
|
|||
}
|
||||
return c.JSON(fiber.Map{"token": t})
|
||||
}
|
||||
|
||||
// CreateProject is a simple handler that creates a new project
|
||||
func (gs *GState) CreateProject(c *fiber.Ctx) error {
|
||||
user := c.Locals("user").(*jwt.Token)
|
||||
|
||||
p := new(types.NewProject)
|
||||
if err := c.BodyParser(p); err != nil {
|
||||
return c.Status(400).SendString(err.Error())
|
||||
}
|
||||
|
||||
// Get the username from the token and set it as the owner of the project
|
||||
// This is ugly but
|
||||
claims := user.Claims.(jwt.MapClaims)
|
||||
p.Owner = claims["name"].(string)
|
||||
|
||||
if err := gs.Db.AddProject(p.Name, p.Description, p.Owner); err != nil {
|
||||
return c.Status(500).SendString(err.Error())
|
||||
}
|
||||
|
||||
return c.Status(200).SendString("Project added")
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package model
|
||||
|
||||
type TimeReport struct {
|
||||
reportId string
|
||||
projectName string
|
||||
userName string
|
||||
userRole string
|
||||
reportDate string
|
||||
timeWorked uint64
|
||||
isSigned bool
|
||||
reportStatus string // Example "draft", "signed", "unsigned"
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
timeReports []TimeReport
|
||||
projectName string
|
||||
projectmembers map[string]User
|
||||
projectRoles map[string]User
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type Account struct {
|
||||
fullName string
|
||||
userName string
|
||||
}
|
||||
|
||||
type Administrator struct {
|
||||
projects map[string]Project
|
||||
Account
|
||||
ProjectMember // comp
|
||||
}
|
||||
|
||||
// Administrator reciever functions
|
||||
func (administrator Administrator) addUser(project *Project, user *User) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (administrator Administrator) removerUser(project *Project, user *User) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (administrator Administrator) deleteProject(project *Project) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (administrator Administrator) changeUserRole(project *Project, user *User) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (administrator *Administrator) login() error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (administrator *Administrator) logout() error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
type ProjectManager struct {
|
||||
managedProjects map[string]Project // projekt som förvaltas av projektledaren
|
||||
totalTime uint64 // total totalt tid arbetat av projektledaren
|
||||
Account
|
||||
ProjectMember // comp
|
||||
}
|
||||
|
||||
// ProjectManager reciever functions
|
||||
func (projectManager ProjectManager) signReport(timeReport *TimeReport, user User) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager ProjectManager) unsignReport(timeReport *TimeReport, user User) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager ProjectManager) getAllReports(project *Project) ([]TimeReport, error) {
|
||||
// WIP
|
||||
return project.timeReports, errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager ProjectManager) assignRole(user *User, project *Project, newRole string) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager ProjectManager) removeMember(project *Project, user *User) error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager ProjectManager) getTotalTime(project *Project) (uint64, error) {
|
||||
// WIP
|
||||
return 0, errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager *ProjectManager) login() error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectManager *ProjectManager) logout() error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
type ProjectMember struct {
|
||||
timereports []TimeReport
|
||||
role string // ?????
|
||||
Account // comp
|
||||
}
|
||||
|
||||
// User reciever functions
|
||||
|
||||
// function used to create a time report, returning a *TimeReport is questionable
|
||||
func (ProjectMember *ProjectMember) createTimeReport(Project *Project) (*TimeReport, error) {
|
||||
// WIP
|
||||
return &TimeReport{}, errors.New("WIP")
|
||||
}
|
||||
|
||||
func (ProjectMember ProjectMember) getTimeReport(timereports *[]TimeReport) (*TimeReport, error) {
|
||||
// WIP
|
||||
return &TimeReport{}, errors.New("WIP")
|
||||
}
|
||||
|
||||
func (ProjectMember *ProjectMember) editTimeReport(timereport *TimeReport) {
|
||||
// timereport.editReport()
|
||||
// WIP
|
||||
}
|
||||
|
||||
func (projectUser ProjectMember) deleteTimeReport(timeReport *TimeReport) error { // Ska bara project manager kunna göra detta? fråga ledarna!
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectUser *ProjectMember) login() error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
func (projectUser *ProjectMember) logout() error {
|
||||
// WIP
|
||||
return errors.New("WIP")
|
||||
}
|
||||
|
||||
type User interface {
|
||||
login()
|
||||
logout()
|
||||
}
|
21
backend/internal/types/project.go
Normal file
21
backend/internal/types/project.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Project is a struct that holds the information about a project
|
||||
type Project struct {
|
||||
ID int `json:"id" db:"id"`
|
||||
Name string `json:"name" db:"name"`
|
||||
Description string `json:"description" db:"description"`
|
||||
Owner string `json:"owner" db:"owner"`
|
||||
Created time.Time `json:"created" db:"created"`
|
||||
}
|
||||
|
||||
// As it arrives from the client
|
||||
type NewProject struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Owner string `json:"owner"`
|
||||
}
|
|
@ -16,6 +16,11 @@ func (u *User) ToPublicUser() (*PublicUser, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
type NewUser struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// PublicUser represents a user that is safe to send over the API (no password)
|
||||
type PublicUser struct {
|
||||
UserId string `json:"userId"`
|
||||
|
|
Loading…
Reference in a new issue