-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Users now can generate access tokens and use them to authenticate with Soft Serve HTTP Git server. It supports basic username & password, generated access tokens, and JWT tokens. As of now there is no way the user can set a password. This will be implemented in a separate PR. Access tokens hashes are stored in the database along with an optional expiry date. Access tokens can be used as the Git user or password in a HTTP clone URL e.g. `https://<token>@git.example.com/repo.git` fix: lint errors fix: ensure default branch on http push fix: address carlos comments
- Loading branch information
1 parent
f69f064
commit a9e5ace
Showing
22 changed files
with
589 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package backend | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"time" | ||
|
||
"github.com/charmbracelet/soft-serve/server/db" | ||
"github.com/charmbracelet/soft-serve/server/proto" | ||
) | ||
|
||
// CreateAccessToken creates an access token for user. | ||
func (b *Backend) CreateAccessToken(ctx context.Context, user proto.User, name string, expiresAt time.Time) (string, error) { | ||
token := GenerateToken() | ||
tokenHash := HashToken(token) | ||
|
||
if err := b.db.TransactionContext(ctx, func(tx *db.Tx) error { | ||
_, err := b.store.CreateAccessToken(ctx, tx, name, user.ID(), tokenHash, expiresAt) | ||
if err != nil { | ||
return db.WrapError(err) | ||
} | ||
|
||
return nil | ||
}); err != nil { | ||
return "", err | ||
} | ||
|
||
return token, nil | ||
} | ||
|
||
// DeleteAccessToken deletes an access token for a user. | ||
func (b *Backend) DeleteAccessToken(ctx context.Context, user proto.User, id int64) error { | ||
err := b.db.TransactionContext(ctx, func(tx *db.Tx) error { | ||
_, err := b.store.GetAccessToken(ctx, tx, id) | ||
if err != nil { | ||
return db.WrapError(err) | ||
} | ||
|
||
if err := b.store.DeleteAccessTokenForUser(ctx, tx, user.ID(), id); err != nil { | ||
return db.WrapError(err) | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
if errors.Is(err, db.ErrRecordNotFound) { | ||
return proto.ErrTokenNotFound | ||
} | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// ListAccessTokens lists access tokens for a user. | ||
func (b *Backend) ListAccessTokens(ctx context.Context, user proto.User) ([]proto.AccessToken, error) { | ||
accessTokens, err := b.store.GetAccessTokensByUserID(ctx, b.db, user.ID()) | ||
if err != nil { | ||
return nil, db.WrapError(err) | ||
} | ||
|
||
var tokens []proto.AccessToken | ||
for _, t := range accessTokens { | ||
token := proto.AccessToken{ | ||
ID: t.ID, | ||
Name: t.Name, | ||
TokenHash: t.Token, | ||
UserID: t.UserID, | ||
CreatedAt: t.CreatedAt, | ||
} | ||
if t.ExpiresAt.Valid { | ||
token.ExpiresAt = t.ExpiresAt.Time | ||
} | ||
|
||
tokens = append(tokens, token) | ||
} | ||
|
||
return tokens, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package proto | ||
|
||
import "time" | ||
|
||
// AccessToken represents an access token. | ||
type AccessToken struct { | ||
ID int64 | ||
Name string | ||
UserID int64 | ||
TokenHash string | ||
ExpiresAt time.Time | ||
CreatedAt time.Time | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.