mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-21 16:40:52 +00:00
fix: extend forgejo_auth_token
table
- Add a `purpose` column, this allows the `forgejo_auth_token` table to be used by other parts of Forgejo, while still enjoying the no-compromise architecture. - Remove the 'roll your own crypto' time limited code functions and migrate them to the `forgejo_auth_token` table. This migration ensures generated codes can only be used for their purpose and ensure they are invalidated after their usage by deleting it from the database, this also should help making auditing of the security code easier, as we're no longer trying to stuff a lot of data into a HMAC construction. -Helper functions are rewritten to ensure a safe-by-design approach to these tokens. - Add the `forgejo_auth_token` to dbconsistency doctor and add it to the `deleteUser` function. - TODO: Add cron job to delete expired authorization tokens. - Unit and integration tests added.
This commit is contained in:
parent
0fa436c373
commit
1ce33aa38d
18 changed files with 448 additions and 256 deletions
|
@ -70,7 +70,7 @@ func SendTestMail(email string) error {
|
|||
}
|
||||
|
||||
// sendUserMail sends a mail to the user
|
||||
func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) {
|
||||
func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) error {
|
||||
locale := translation.NewLocale(language)
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
|
@ -84,47 +84,66 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s
|
|||
var content bytes.Buffer
|
||||
|
||||
if err := bodyTemplates.ExecuteTemplate(&content, string(tpl), data); err != nil {
|
||||
log.Error("Template: %v", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
msg := NewMessage(u.EmailTo(), subject, content.String())
|
||||
msg.Info = fmt.Sprintf("UID: %d, %s", u.ID, info)
|
||||
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendActivateAccountMail sends an activation mail to the user (new user registration)
|
||||
func SendActivateAccountMail(locale translation.Locale, u *user_model.User) {
|
||||
func SendActivateAccountMail(ctx context.Context, u *user_model.User) error {
|
||||
if setting.MailService == nil {
|
||||
// No mail service configured
|
||||
return
|
||||
return nil
|
||||
}
|
||||
sendUserMail(locale.Language(), u, mailAuthActivate, u.GenerateEmailActivateCode(u.Email), locale.TrString("mail.activate_account"), "activate account")
|
||||
|
||||
locale := translation.NewLocale(u.Language)
|
||||
code, err := u.GenerateEmailAuthorizationCode(ctx, auth_model.UserActivation)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sendUserMail(locale.Language(), u, mailAuthActivate, code, locale.TrString("mail.activate_account"), "activate account")
|
||||
}
|
||||
|
||||
// SendResetPasswordMail sends a password reset mail to the user
|
||||
func SendResetPasswordMail(u *user_model.User) {
|
||||
func SendResetPasswordMail(ctx context.Context, u *user_model.User) error {
|
||||
if setting.MailService == nil {
|
||||
// No mail service configured
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
locale := translation.NewLocale(u.Language)
|
||||
sendUserMail(u.Language, u, mailAuthResetPassword, u.GenerateEmailActivateCode(u.Email), locale.TrString("mail.reset_password"), "recover account")
|
||||
code, err := u.GenerateEmailAuthorizationCode(ctx, auth_model.PasswordReset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sendUserMail(u.Language, u, mailAuthResetPassword, code, locale.TrString("mail.reset_password"), "recover account")
|
||||
}
|
||||
|
||||
// SendActivateEmailMail sends confirmation email to confirm new email address
|
||||
func SendActivateEmailMail(u *user_model.User, email string) {
|
||||
func SendActivateEmailMail(ctx context.Context, u *user_model.User, email string) error {
|
||||
if setting.MailService == nil {
|
||||
// No mail service configured
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
locale := translation.NewLocale(u.Language)
|
||||
code, err := u.GenerateEmailAuthorizationCode(ctx, auth_model.EmailActivation(email))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := map[string]any{
|
||||
"locale": locale,
|
||||
"DisplayName": u.DisplayName(),
|
||||
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
|
||||
"Code": u.GenerateEmailActivateCode(email),
|
||||
"Code": code,
|
||||
"Email": email,
|
||||
"Language": locale.Language(),
|
||||
}
|
||||
|
@ -132,14 +151,14 @@ func SendActivateEmailMail(u *user_model.User, email string) {
|
|||
var content bytes.Buffer
|
||||
|
||||
if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuthActivateEmail), data); err != nil {
|
||||
log.Error("Template: %v", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
msg := NewMessage(email, locale.TrString("mail.activate_email"), content.String())
|
||||
msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID)
|
||||
|
||||
SendAsync(msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue