diff --git a/pkg/database/repository/base.go b/pkg/database/repository/base.go
new file mode 100644
index 0000000000000000000000000000000000000000..a9d69c990f2425f791b8e4ce2746a75452fcfb2f
--- /dev/null
+++ b/pkg/database/repository/base.go
@@ -0,0 +1,5 @@
+package repository
+
+import "errors"
+
+var ErrRecordNotFound = errors.New("record not found")
diff --git a/pkg/database/sql/user.go b/pkg/database/sql/user.go
index 6b1cf0fd16436f1cbce0e4c0c94d23d372ec31b9..2ec86229435c1508c25f5b67f98178a6cfd67647 100644
--- a/pkg/database/sql/user.go
+++ b/pkg/database/sql/user.go
@@ -2,6 +2,7 @@ package sql
import (
"context"
+ "errors"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
@@ -82,7 +83,7 @@ WithContext(ctx).
Find(&users)
if result.Error != nil {
- return nil, result.Error
+ return nil, wrapError(result.Error)
}
return users.ToModel(), nil
@@ -95,7 +96,7 @@ WithContext(ctx).
First(user)
if result.Error != nil {
- return nil, result.Error
+ return nil, wrapError(result.Error)
}
return user, nil
@@ -113,7 +114,7 @@ Where("username = ?", username).
First(&userID)
if result.Error != nil {
- return 0, result.Error
+ return 0, wrapError(result.Error)
}
return userID.ID, nil
@@ -131,7 +132,7 @@ Where("id = ?", id).
First(&userPassword)
if result.Error != nil {
- return nil, result.Error
+ return nil, wrapError(result.Error)
}
return userPassword.Password, nil
@@ -150,7 +151,7 @@ result := self.db.
WithContext(ctx).
Create(user)
if result.Error != nil {
- return 0, result.Error
+ return 0, wrapError(result.Error)
}
return user.Model.ID, nil
@@ -172,7 +173,7 @@ WithContext(ctx).
Omit("password").
Updates(user)
if result.Error != nil {
- return result.Error
+ return wrapError(result.Error)
}
return nil
@@ -189,7 +190,7 @@ result := self.db.
WithContext(ctx).
Delete(user)
if result.Error != nil {
- return result.Error
+ return wrapError(result.Error)
}
return nil
}
@@ -203,7 +204,7 @@ Select("count(id) > 0").
Find(&exists)
if result.Error != nil {
- return false, result.Error
+ return false, wrapError(result.Error)
}
return exists, nil
@@ -220,7 +221,7 @@ Where("id = ?", id).
First(&userPath)
if result.Error != nil {
- return "", result.Error
+ return "", wrapError(result.Error)
}
return userPath, nil
@@ -233,5 +234,12 @@ Model(&User{}).
Where("id = ?", id).
Update("password", password)
- return result.Error
+ return wrapError(result.Error)
+}
+
+func wrapError(err error) error {
+ if errors.Is(err, gorm.ErrRecordNotFound) {
+ return repository.ErrRecordNotFound
+ }
+ return err
}
diff --git a/pkg/service/auth.go b/pkg/service/auth.go
index 30e574a9690f2c33f6a89f08fa089f8776020102..2fc06e383f8f34d2e1ac843d1d48fb1930c6f80a 100644
--- a/pkg/service/auth.go
+++ b/pkg/service/auth.go
@@ -21,6 +21,8 @@ userRepository repository.UserRepository
key []byte
}
+var InvalidLogin = errors.New("Invalid login")
+
func NewAuthController(
authRepository repository.AuthRepository,
userRepository repository.UserRepository,
@@ -35,17 +37,21 @@ }
func (c *AuthController) Login(ctx context.Context, username, password []byte) ([]byte, error) {
id, err := c.authRepository.GetIDByUsername(ctx, string(username))
- if err != nil {
+ if errors.Is(err, repository.ErrRecordNotFound) {
+ return nil, InvalidLogin
+ } else if err != nil {
return nil, err
}
hashedPassword, err := c.authRepository.GetPassword(ctx, id)
- if err != nil {
+ if errors.Is(err, repository.ErrRecordNotFound) {
+ return nil, InvalidLogin
+ } else if err != nil {
return nil, err
}
if err := bcrypt.CompareHashAndPassword(hashedPassword, password); err != nil {
- return nil, err
+ return nil, InvalidLogin
}
token := &Token{
diff --git a/pkg/view/auth.go b/pkg/view/auth.go
index 1b87235ed7a45f011cc695a650c793d3d493bc91..8d870352e8b7220c8df36582adaeeab7beb054b1 100644
--- a/pkg/view/auth.go
+++ b/pkg/view/auth.go
@@ -2,6 +2,7 @@ package view
import (
"encoding/base64"
+ "errors"
"net/http"
"git.sr.ht/~gabrielgio/img/pkg/ext"
@@ -45,6 +46,15 @@ password = []byte(r.FormValue("password"))
)
auth, err := v.userController.Login(r.Context(), username, password)
+
+ if errors.Is(err, service.InvalidLogin) {
+ templates.WritePageTemplate(w, &templates.LoginPage{
+ Username: r.FormValue("username"),
+ Err: err.Error(),
+ })
+ return nil
+ }
+
if err != nil {
return err
}
diff --git a/scss/main.scss b/scss/main.scss
index 887745238075345e54a2f47e69baa22d7e1beb31..532a38a801bf6cc40f6e57780c6fc35505883439 100644
--- a/scss/main.scss
+++ b/scss/main.scss
@@ -1,13 +1,11 @@
$breakpoint: 360px;
-
+$radius: 0px;
$tablet: 480px;
$body-font-size: 1rem;
-$radius-rounded: 0;
$navbar-breakpoint: $breakpoint;
$panel-item-border: 1px solid hsl(0, 0%, 93%);
-$panel-radius: 0;
$panel-shadow: 0;
$card-shadow: 0;
@@ -17,7 +15,6 @@
$table-cell-padding: 0.5em;
$table-cell-border-width: 0;
-$tag-radius: 0;
$tag-delete-margin: 15px;
$title-weight: normal;
diff --git a/templates/login.qtpl b/templates/login.qtpl
index 56394d001c32c59db586e49112fb57fd71ea0463..c68fb5f8dd68488cbf0e1e5b2bc150c5fcfe806a 100644
--- a/templates/login.qtpl
+++ b/templates/login.qtpl
@@ -1,5 +1,8 @@
{% code
-type LoginPage struct {}
+type LoginPage struct {
+ Username string
+ Err string
+ }
%}
{% func (p *LoginPage) Title() %}Login{% endfunc %}
@@ -9,7 +12,7 @@ <form action="/login" method="post">
<div class="field">
<label class="label">Username</label>
<div class="control">
- <input class="input" name="username" type="text">
+ <input class="input" name="username" value="{%s p.Username %}" type="text">
</div>
</div>
<div class="field">
@@ -18,9 +21,18 @@ <div class="control">
<input class="input" name="password" type="password">
</div>
</div>
+ <div class="field is-grouped is-grouped-right">
+ <input class="button" value="login" type="submit">
+ </div>
+ {% if p.Err != "" %}
<div class="field">
- <input class="button is-pulled-right" value="login" type="submit">
+ <article class="message is-danger">
+ <div class="message-body">
+ {%s p.Err %}
+ </div>
+ </article>
</div>
+ {% endif %}
</form>
{% endfunc %}
diff --git a/templates/register.qtpl b/templates/register.qtpl
index 115edfeab3e33fe1f11b2dbf6afc9f3587e40a88..4d3c545dd718c85dc5e8395cdeb5e2694370745a 100644
--- a/templates/register.qtpl
+++ b/templates/register.qtpl
@@ -25,8 +25,8 @@ <div class="control">
<input class="input" name="path" type="text">
</div>
</div>
- <div class="field">
- <input class="button is-pulled-right" value="Save" type="submit">
+ <div class="field is-grouped is-grouped-right">
+ <input class="button" value="Save" type="submit">
</div>
</form>
{% endfunc %}