1
0
Fork 0
mirror of https://codeberg.org/forgejo/forgejo.git synced 2025-08-05 09:55:20 +02:00

feat(auth): add ability to regenerate access tokens (#6963)

- Add the ability to regenerate existing access tokens in the UI. This preserves the ID of the access token, but generates a new salt and token contents.
- Integration test added.
- Unit test added.
- Resolves #6880

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6963
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Dmitrii Sharshakov <d3dx12.xx@gmail.com>
Co-committed-by: Dmitrii Sharshakov <d3dx12.xx@gmail.com>
This commit is contained in:
Dmitrii Sharshakov 2025-03-08 10:42:36 +00:00 committed by Gusted
parent 9dea54a9d6
commit 30982b9e7b
8 changed files with 176 additions and 7 deletions

View file

@ -98,6 +98,15 @@ func init() {
// NewAccessToken creates new access token.
func NewAccessToken(ctx context.Context, t *AccessToken) error {
err := generateAccessToken(t)
if err != nil {
return err
}
_, err = db.GetEngine(ctx).Insert(t)
return err
}
func generateAccessToken(t *AccessToken) error {
salt, err := util.CryptoRandomString(10)
if err != nil {
return err
@ -110,8 +119,7 @@ func NewAccessToken(ctx context.Context, t *AccessToken) error {
t.Token = hex.EncodeToString(token)
t.TokenHash = HashToken(t.Token, t.TokenSalt)
t.TokenLastEight = t.Token[len(t.Token)-8:]
_, err = db.GetEngine(ctx).Insert(t)
return err
return nil
}
// DisplayPublicOnly whether to display this as a public-only token.
@ -234,3 +242,25 @@ func DeleteAccessTokenByID(ctx context.Context, id, userID int64) error {
}
return nil
}
// RegenerateAccessTokenByID regenerates access token by given ID.
// It regenerates token and salt, as well as updates the creation time.
func RegenerateAccessTokenByID(ctx context.Context, id, userID int64) (*AccessToken, error) {
t := &AccessToken{}
found, err := db.GetEngine(ctx).Where("id = ? AND uid = ?", id, userID).Get(t)
if err != nil {
return nil, err
} else if !found {
return nil, ErrAccessTokenNotExist{}
}
err = generateAccessToken(t)
if err != nil {
return nil, err
}
// Reset the creation time, token is unused
t.UpdatedUnix = timeutil.TimeStampNow()
return t, UpdateAccessToken(ctx, t)
}