Compare commits

..

2 Commits

Author SHA1 Message Date
lbenedar
91f5a63366 ch11.2 2026-03-06 11:48:48 +03:00
lbenedar
6eee11400c ch11.1 2026-03-06 11:34:43 +03:00
6 changed files with 86 additions and 6 deletions

View File

@@ -117,3 +117,23 @@ func (app *application) snippetCreatePost(w http.ResponseWriter, r *http.Request
http.Redirect(w, r, fmt.Sprintf("/snippet/view/%d", id), http.StatusSeeOther) http.Redirect(w, r, fmt.Sprintf("/snippet/view/%d", id), http.StatusSeeOther)
} }
func (app *application) userSignupPost(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Create a new user...")
}
func (app *application) userLoginPost(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Login the user...")
}
func (app *application) userLogoutPost(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Logout the user...")
}
func (app *application) userSignup(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Display a HTML for signing up a new user...")
}
func (app *application) userLogin(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Display a HTML for log in a user...")
}

View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"crypto/tls"
"database/sql" "database/sql"
"flag" "flag"
"html/template" "html/template"
@@ -21,6 +22,7 @@ type application struct {
errorLog *log.Logger errorLog *log.Logger
infoLog *log.Logger infoLog *log.Logger
snippets *models.SnippetModel snippets *models.SnippetModel
users *models.UserModel
templateCache map[string]*template.Template templateCache map[string]*template.Template
formDecoder *form.Decoder formDecoder *form.Decoder
sessionManager *scs.SessionManager sessionManager *scs.SessionManager
@@ -62,15 +64,24 @@ func main() {
errorLog: errorLog, errorLog: errorLog,
infoLog: infoLog, infoLog: infoLog,
snippets: &models.SnippetModel{DB: db}, snippets: &models.SnippetModel{DB: db},
users: &models.UserModel{DB: db},
templateCache: templateCache, templateCache: templateCache,
formDecoder: formDecoder, formDecoder: formDecoder,
sessionManager: sessionManager, sessionManager: sessionManager,
} }
tlsConfig := &tls.Config{
CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256}, // TODO: read about CurvePreferences
}
srv := &http.Server{ srv := &http.Server{
Addr: cfg.addr, Addr: cfg.addr,
ErrorLog: errorLog, ErrorLog: errorLog,
Handler: app.routes(), Handler: app.routes(),
TLSConfig: tlsConfig,
IdleTimeout: time.Minute,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
} }
infoLog.Printf("Starting server on %s", cfg.addr) infoLog.Printf("Starting server on %s", cfg.addr)

View File

@@ -24,6 +24,12 @@ func (app *application) routes() http.Handler {
router.Handler(http.MethodGet, "/snippet/create", dynamic.ThenFunc(app.snippetCreate)) router.Handler(http.MethodGet, "/snippet/create", dynamic.ThenFunc(app.snippetCreate))
router.Handler(http.MethodPost, "/snippet/create", dynamic.ThenFunc(app.snippetCreatePost)) router.Handler(http.MethodPost, "/snippet/create", dynamic.ThenFunc(app.snippetCreatePost))
router.Handler(http.MethodGet, "/user/signup", dynamic.ThenFunc(app.userSignup))
router.Handler(http.MethodPost, "/user/signup", dynamic.ThenFunc(app.userSignupPost))
router.Handler(http.MethodGet, "/user/login", dynamic.ThenFunc(app.userLogin))
router.Handler(http.MethodPost, "/user/login", dynamic.ThenFunc(app.userLoginPost))
router.Handler(http.MethodPost, "/user/logout", dynamic.ThenFunc(app.userLogoutPost))
standard := alice.New(app.recoverPanic, app.logRequest, secureHeaders) standard := alice.New(app.recoverPanic, app.logRequest, secureHeaders)
return standard.Then(router) return standard.Then(router)
} }

View File

@@ -2,4 +2,8 @@ package models
import "errors" import "errors"
var ErrNoRecord = errors.New("models: no matching record found") var (
ErrNoRecord = errors.New("models: no matching record found")
ErrInvalidCredentials = errors.New("models: invalid credentials")
ErrDuplicateEmail = errors.New("models: duplicate email")
)

30
internal/models/users.go Normal file
View File

@@ -0,0 +1,30 @@
package models
import (
"database/sql"
"time"
)
type User struct {
ID int
Name string
Email string
HashedPassword []byte
Created time.Time
}
type UserModel struct {
DB *sql.DB
}
func (m *UserModel) Insert(name, email, password string) error {
return nil
}
func (m *UserModel) Authenticate(email, password string) (int, error) {
return 0, nil
}
func (m *UserModel) Exists(id int) (bool, error) {
return false, nil
}

View File

@@ -1,6 +1,15 @@
{{define "nav"}} {{define "nav"}}
<nav> <nav>
<a href='/'>Home</a> <div>
<a href='/snippet/create'>Create snippet</a> <a href='/'>Home</a>
<a href='/snippet/create'>Create snippet</a>
</div>
<div>
<a href='/user/signup'>Signup</a>
<a href='/user/login'>Login</a>
<form action='/user/logout' method='POST'>
<button>Logout</button>
</form>
</div>
</nav> </nav>
{{end}} {{end}}