Skip to content

Commit

Permalink
Add login to users - #15
Browse files Browse the repository at this point in the history
  • Loading branch information
Igor Polyakov committed Jun 22, 2024
1 parent 64b0a3f commit b6a02e9
Show file tree
Hide file tree
Showing 11 changed files with 952 additions and 855 deletions.
1,662 changes: 834 additions & 828 deletions api/openapi.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
github.com/go-chi/chi v1.5.5 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/jaswdr/faker/v2 v2.3.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/stretchr/testify v1.9.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
github.com/jaswdr/faker/v2 v2.3.0 h1:jgQ9UmU2Eb5tSQ8JkUS4tPoyTM2OtThQpOpwk7Fa9RY=
github.com/jaswdr/faker/v2 v2.3.0/go.mod h1:ROK8xwQV0hYOLDUtxCQgHGcl10jbVzIvqHxcIDdwY2Q=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
Expand Down
2 changes: 2 additions & 0 deletions internal/app/database/struct_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func RegisterAllUpdates() map[string][]DatabaseUpdateFunc {
allUpdates = RegisterDatabaseUpdate(allUpdates, DatabaseUpdate_update0011_update0011testdata)
allUpdates = RegisterDatabaseUpdate(allUpdates, DatabaseUpdate_update0011_update0012)
allUpdates = RegisterDatabaseUpdate(allUpdates, DatabaseUpdate_update0012_update0012testdata)
allUpdates = RegisterDatabaseUpdate(allUpdates, DatabaseUpdate_update0012_update0013)
allUpdates = RegisterDatabaseUpdate(allUpdates, DatabaseUpdate_update0013_update0013testdata)
return allUpdates
}

Expand Down
30 changes: 30 additions & 0 deletions internal/app/database/update0012_update0013.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package database

import (
"database/sql"
"log/slog"
"runtime"
)

func DatabaseUpdate_update0012_update0013(db *sql.DB, getInfo bool) (string, string, string, error) {

// WARNING!!!
// Do not change the update if it has already been installed by other developers or in production.
// To correct the database, create a new update and register it in the list of updates.

fromUpdateId, toUpdateId := ParseNameFuncUpdate(runtime.Caller(0))
description := "Added column display_name to users"
if getInfo {
return fromUpdateId, toUpdateId, description, nil
}
query := `
ALTER TABLE users
ADD COLUMN display_name varchar(255);
`
_, err := db.Exec(query)
if err != nil {
slog.Error("Problem with update, query: " + query + "\n error:" + err.Error())
return fromUpdateId, toUpdateId, description, err
}
return fromUpdateId, toUpdateId, description, nil
}
46 changes: 46 additions & 0 deletions internal/app/database/update0013_update0013testdata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package database

import (
"database/sql"
"fmt"
"log"
"log/slog"
"runtime"

"github.com/jaswdr/faker/v2"
)

func DatabaseUpdate_update0013_update0013testdata(db *sql.DB, getInfo bool) (string, string, string, error) {

// WARNING!!!
// Do not change the update if it has already been installed by other developers or in production.
// To correct the database, create a new update and register it in the list of updates.

fromUpdateId, toUpdateId := ParseNameFuncUpdate(runtime.Caller(0))
description := "Insert test data to game_services"
if getInfo {
return fromUpdateId, toUpdateId, description, nil
}
query := `
SELECT id from users
`
rows, err := db.Query(query)
if err != nil {
slog.Error("Problem with select, query: " + query + "\n error:" + err.Error())
return fromUpdateId, toUpdateId, description, err
}
fake := faker.New()
for rows.Next() {
var id int
if err := rows.Scan(&id); err != nil {
log.Fatalf("Error scanning row: %v", err)
}
query := fmt.Sprintf("UPDATE users SET display_name = '%s' WHERE id = %d", fake.Person().Name(), id)
_, err := db.Exec(query)
if err != nil {
slog.Error("Problem with update, query: " + query + "\n error:" + err.Error())
return fromUpdateId, toUpdateId, description, err
}
}
return fromUpdateId, toUpdateId, description, nil
}
1 change: 1 addition & 0 deletions internal/app/db/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "ctf01d/internal/app/server"

type User struct {
Id int `db:"id"`
DisplayName string `db:"display_name"`
Username string `db:"user_name"`
Role server.UserRequestRole `db:"role"`
AvatarUrl string `db:"avatar_url"`
Expand Down
10 changes: 5 additions & 5 deletions internal/app/handlers/sessions.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ import (
func (h *Handlers) PostApiV1AuthSignin(w http.ResponseWriter, r *http.Request) {
var req server.PostApiV1AuthSigninJSONBody
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
slog.Warn(err.Error(), "handler", "LoginSessionHandler")
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignin")
http.Error(w, "Invalid request body", http.StatusBadRequest)
return
}
userRepo := repository.NewUserRepository(h.DB)
user, err := userRepo.GetByUserName(r.Context(), *req.UserName)
if err != nil || !api_helpers.CheckPasswordHash(*req.Password, user.PasswordHash) {
slog.Warn(err.Error(), "handler", "LoginSessionHandler")
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignin")
api_helpers.RespondWithJSON(w, http.StatusUnauthorized, map[string]string{"error": "Invalid password or user"})
return
}

repo := repository.NewSessionRepository(h.DB)
sessionId, err := repo.StoreSessionInDB(r.Context(), user.Id)
if err != nil {
slog.Warn(err.Error(), "handler", "LoginSessionHandler")
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignin")
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Failed to store session"})
return
}
Expand All @@ -47,14 +47,14 @@ func (h *Handlers) PostApiV1AuthSignin(w http.ResponseWriter, r *http.Request) {
func (h *Handlers) PostApiV1AuthSignout(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session_id")
if err != nil {
slog.Warn(err.Error(), "handler", "LogoutSessionHandler")
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignout")
api_helpers.RespondWithJSON(w, http.StatusUnauthorized, map[string]string{"error": "No session found"})
return
}
repo := repository.NewSessionRepository(h.DB)
err = repo.DeleteSessionInDB(r.Context(), cookie.Value)
if err != nil {
slog.Warn(err.Error(), "handler", "LogoutSessionHandler")
slog.Warn(err.Error(), "handler", "PostApiV1AuthSignout")
api_helpers.RespondWithJSON(w, http.StatusInternalServerError, map[string]string{"error": "Failed to delete session"})
return
}
Expand Down
17 changes: 9 additions & 8 deletions internal/app/repository/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ func NewUserRepository(db *sql.DB) UserRepository {
}

func (r *userRepo) Create(ctx context.Context, user *models.User) error {
query := `INSERT INTO users (user_name, avatar_url, role, status, password_hash) VALUES ($1, $2, $3, $4, $5) RETURNING id`
err := r.db.QueryRowContext(ctx, query, user.Username, user.AvatarUrl, user.Role, user.Status, user.PasswordHash).Scan(&user.Id)
query := `INSERT INTO users (display_name, user_name, avatar_url, role, status, password_hash) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id`
err := r.db.QueryRowContext(ctx, query, user.DisplayName, user.Username, user.AvatarUrl, user.Role, user.Status, user.PasswordHash).Scan(&user.Id)
if err != nil {
return err
}

return nil
}

Expand All @@ -45,9 +46,9 @@ func (r *userRepo) AddUserToTeams(ctx context.Context, userId int, teamIds *[]in
}

func (r *userRepo) GetById(ctx context.Context, id int) (*models.User, error) {
query := `SELECT id, user_name, avatar_url, role, status FROM users WHERE id = $1`
query := `SELECT id, display_name, user_name, avatar_url, role, status FROM users WHERE id = $1`
user := &models.User{}
err := r.db.QueryRowContext(ctx, query, id).Scan(&user.Id, &user.Username, &user.AvatarUrl, &user.Role, &user.Status)
err := r.db.QueryRowContext(ctx, query, id).Scan(&user.Id, &user.DisplayName, &user.Username, &user.AvatarUrl, &user.Role, &user.Status)
if err != nil {
return nil, err
}
Expand All @@ -65,8 +66,8 @@ func (r *userRepo) GetByUserName(ctx context.Context, name string) (*models.User
}

func (r *userRepo) Update(ctx context.Context, user *models.User) error {
query := `UPDATE users SET user_name = $1, avatar_url = $2, role = $3, status = $4, password_hash = $5 WHERE id = $6`
_, err := r.db.ExecContext(ctx, query, user.Username, user.AvatarUrl, user.Role, user.Status, user.PasswordHash, user.Id)
query := `UPDATE users SET user_name = $1, avatar_url = $2, role = $3, status = $4, password_hash = $5, login = $6 WHERE id = $7`
_, err := r.db.ExecContext(ctx, query, user.Username, user.AvatarUrl, user.Role, user.Status, user.PasswordHash, user.DisplayName, user.Id)
return err
}

Expand All @@ -93,7 +94,7 @@ func (r *userRepo) Delete(ctx context.Context, id int) error {
}

func (r *userRepo) List(ctx context.Context) ([]*models.User, error) {
query := `SELECT id, user_name, avatar_url, role, status FROM users`
query := `SELECT id, display_name, user_name, avatar_url, role, status FROM users`
rows, err := r.db.QueryContext(ctx, query)
if err != nil {
return nil, err
Expand All @@ -103,7 +104,7 @@ func (r *userRepo) List(ctx context.Context) ([]*models.User, error) {
var users []*models.User
for rows.Next() {
var user models.User
if err := rows.Scan(&user.Id, &user.Username, &user.AvatarUrl, &user.Role, &user.Status); err != nil {
if err := rows.Scan(&user.Id, &user.DisplayName, &user.Username, &user.AvatarUrl, &user.Role, &user.Status); err != nil {
return nil, err
}
users = append(users, &user)
Expand Down
14 changes: 10 additions & 4 deletions internal/app/server/server.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 12 additions & 10 deletions internal/app/view/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@ import (
)

type User struct {
Id int `json:"id"`
Username string `json:"user_name"`
Role string `json:"role,omitempty"`
AvatarUrl string `json:"avatar_url,omitempty"`
Status string `json:"status,omitempty"`
Id int `json:"id"`
DisplayName string `json:"display_name"`
Username string `json:"user_name"`
Role string `json:"role,omitempty"`
AvatarUrl string `json:"avatar_url,omitempty"`
Status string `json:"status,omitempty"`
}

func NewUserFromModel(u *db.User) *server.UserResponse {
userRole := helpers.ConvertUserRequestRoleToUserResponseRole(u.Role)
return &server.UserResponse{
Id: &u.Id,
UserName: &u.Username,
Role: &userRole,
AvatarUrl: &u.AvatarUrl,
Status: &u.Status,
Id: &u.Id,
UserName: &u.Username,
DisplayName: &u.DisplayName,
Role: &userRole,
AvatarUrl: &u.AvatarUrl,
Status: &u.Status,
}
}

Expand Down

0 comments on commit b6a02e9

Please sign in to comment.