mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-31 02:28:31 -04:00
feat(authguest): moved redeem from storage layer to service layer
This commit is contained in:
1 parent
46dce34dd6
commit
5b7fd47e8e
8 files changed
+35
-111
No files matched your search
@@ -26,6 +26,11 @@ func writeError(w http.ResponseWriter, status int, body errorResponse) {
|
||||
}
|
||||
|
||||
func writeGuestError(w http.ResponseWriter, err error) {
|
||||
if errors.Is(err, authguest.ErrEventsNotConfigured) {
|
||||
writeError(w, http.StatusServiceUnavailable, errorResponse{ErrorType: "serviceUnavailable", Message: err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
var ge *authguest.GuestError
|
||||
if !errors.As(err, &ge) {
|
||||
writeError(w, http.StatusInternalServerError, errorResponse{ErrorType: "internalError", Message: "An internal error occurred."})
|
||||
|
||||
@@ -66,6 +66,12 @@ func TestRenewHandlerErrorMapping(t *testing.T) {
|
||||
wantStatus: http.StatusInternalServerError,
|
||||
wantType: "internalError",
|
||||
},
|
||||
{
|
||||
name: "events not configured",
|
||||
err: authguest.ErrEventsNotConfigured,
|
||||
wantStatus: http.StatusServiceUnavailable,
|
||||
wantType: "serviceUnavailable",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -119,11 +119,14 @@ func (s *AuthGuestService) Redeem(ctx context.Context, tokenString string) (*Ses
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.store.Redeem(rec.ShareIDHash); err != nil {
|
||||
if errors.Is(err, storage.ErrAlreadyRedeemed) {
|
||||
return nil, &GuestError{ErrorType: ErrAlreadyRedeemed, ShareID: rec.ShareID}
|
||||
if err := s.store.Update(rec.ShareIDHash, func(r *storage.Record) error {
|
||||
if r.Redeemed {
|
||||
return ErrAlreadyRedeemed
|
||||
}
|
||||
return nil, err
|
||||
r.Redeemed = true
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, &GuestError{ErrorType: err, ShareID: rec.ShareID}
|
||||
}
|
||||
|
||||
sessionToken, err := s.jwtService.Sign(rec.ShareID)
|
||||
|
||||
@@ -253,10 +253,9 @@ func TestValidateShare(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRedeem(t *testing.T) {
|
||||
store := storagemocks.NewManager(t)
|
||||
store := storage.NewFileManager(t.TempDir())
|
||||
tok, rec := newToken(t)
|
||||
store.On("Get", rec.ShareIDHash).Return(rec, nil)
|
||||
store.On("Redeem", rec.ShareIDHash).Return(nil)
|
||||
require.NoError(t, store.Add(rec))
|
||||
|
||||
share := &collaboration.Share{Id: &collaboration.ShareId{OpaqueId: testShareID}}
|
||||
s := newRedeemService(t, store, newGatewayMock(&collaboration.GetShareResponse{
|
||||
@@ -269,14 +268,16 @@ func TestRedeem(t *testing.T) {
|
||||
require.NotEmpty(t, result.SessionToken)
|
||||
assert.Equal(t, testShareID, result.ShareID)
|
||||
|
||||
store.AssertCalled(t, "Redeem", rec.ShareIDHash)
|
||||
got, err := store.Get(rec.ShareIDHash)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, got.Redeemed)
|
||||
}
|
||||
|
||||
func TestRedeemAlreadyRedeemed(t *testing.T) {
|
||||
store := storagemocks.NewManager(t)
|
||||
store := storage.NewFileManager(t.TempDir())
|
||||
tok, rec := newToken(t)
|
||||
store.On("Get", rec.ShareIDHash).Return(rec, nil)
|
||||
store.On("Redeem", rec.ShareIDHash).Return(storage.ErrAlreadyRedeemed)
|
||||
rec.Redeemed = true
|
||||
require.NoError(t, store.Add(rec))
|
||||
|
||||
share := &collaboration.Share{Id: &collaboration.ShareId{OpaqueId: testShareID}}
|
||||
s := newRedeemService(t, store, newGatewayMock(&collaboration.GetShareResponse{
|
||||
|
||||
@@ -83,26 +83,6 @@ func (s *FileManager) Remove(shareIDHash string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FileManager) Redeem(shareIDHash string) error {
|
||||
lock, err := s.lockRecord(shareIDHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { _ = lock.Unlock() }()
|
||||
|
||||
rec, err := s.get(shareIDHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rec.Redeemed {
|
||||
return ErrAlreadyRedeemed
|
||||
}
|
||||
|
||||
rec.Redeemed = true
|
||||
return s.upsert(rec)
|
||||
}
|
||||
|
||||
// Update applies fn to the record under the record lock and writes it back.
|
||||
// If fn returns an error the record is left unchanged.
|
||||
func (s *FileManager) Update(shareIDHash string, fn func(*Record) error) error {
|
||||
|
||||
@@ -95,31 +95,6 @@ func TestFileManagerRemoveMissing(t *testing.T) {
|
||||
assert.ErrorIs(t, err, ErrNotFound)
|
||||
}
|
||||
|
||||
func TestFileManagerRedeem(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
s := NewFileManager(dir)
|
||||
|
||||
rec := newRecord("e0123456-7890-abcd-ef01-234567890abc")
|
||||
require.NoError(t, s.Add(rec))
|
||||
|
||||
require.NoError(t, s.Redeem(rec.ShareIDHash))
|
||||
|
||||
got, err := s.Get(rec.ShareIDHash)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, got.Redeemed)
|
||||
|
||||
err = s.Redeem(rec.ShareIDHash)
|
||||
assert.ErrorIs(t, err, ErrAlreadyRedeemed)
|
||||
}
|
||||
|
||||
func TestFileManagerRedeemMissing(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
s := NewFileManager(dir)
|
||||
|
||||
err := s.Redeem("doesnotexist")
|
||||
assert.ErrorIs(t, err, ErrNotFound)
|
||||
}
|
||||
|
||||
func TestFileManagerUpdate(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
s := NewFileManager(dir)
|
||||
@@ -191,7 +166,7 @@ func TestFileManagerAddConcurrent(t *testing.T) {
|
||||
assert.Equal(t, int32(1), success.Load())
|
||||
}
|
||||
|
||||
func TestFileManagerRedeemConcurrent(t *testing.T) {
|
||||
func TestFileManagerUpdateConcurrent(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
s := NewFileManager(dir)
|
||||
|
||||
@@ -207,7 +182,14 @@ func TestFileManagerRedeemConcurrent(t *testing.T) {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := s.Redeem(rec.ShareIDHash); err == nil {
|
||||
err := s.Update(rec.ShareIDHash, func(r *Record) error {
|
||||
if r.Redeemed {
|
||||
return errors.New("already set")
|
||||
}
|
||||
r.Redeemed = true
|
||||
return nil
|
||||
})
|
||||
if err == nil {
|
||||
success.Add(1)
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -147,57 +147,6 @@ func (_c *Manager_Get_Call) RunAndReturn(run func(shareIDHash string) (storage.R
|
||||
return _c
|
||||
}
|
||||
|
||||
// Redeem provides a mock function for the type Manager
|
||||
func (_mock *Manager) Redeem(shareIDHash string) error {
|
||||
ret := _mock.Called(shareIDHash)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Redeem")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if returnFunc, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = returnFunc(shareIDHash)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
return r0
|
||||
}
|
||||
|
||||
// Manager_Redeem_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Redeem'
|
||||
type Manager_Redeem_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// Redeem is a helper method to define mock.On call
|
||||
// - shareIDHash string
|
||||
func (_e *Manager_Expecter) Redeem(shareIDHash any) *Manager_Redeem_Call {
|
||||
return &Manager_Redeem_Call{Call: _e.mock.On("Redeem", shareIDHash)}
|
||||
}
|
||||
|
||||
func (_c *Manager_Redeem_Call) Run(run func(shareIDHash string)) *Manager_Redeem_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
var arg0 string
|
||||
if args[0] != nil {
|
||||
arg0 = args[0].(string)
|
||||
}
|
||||
run(
|
||||
arg0,
|
||||
)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *Manager_Redeem_Call) Return(err error) *Manager_Redeem_Call {
|
||||
_c.Call.Return(err)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *Manager_Redeem_Call) RunAndReturn(run func(shareIDHash string) error) *Manager_Redeem_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// Remove provides a mock function for the type Manager
|
||||
func (_mock *Manager) Remove(shareIDHash string) error {
|
||||
ret := _mock.Called(shareIDHash)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
)
|
||||
|
||||
var ErrNotFound = errors.New("record not found")
|
||||
var ErrAlreadyRedeemed = errors.New("token already redeemed")
|
||||
var ErrInvalidHash = errors.New("invalid share id hash")
|
||||
|
||||
// Record holds the data persisted for a guest share token.
|
||||
@@ -27,6 +26,5 @@ type Manager interface {
|
||||
Add(rec Record) error
|
||||
Get(shareIDHash string) (Record, error)
|
||||
Remove(shareIDHash string) error
|
||||
Redeem(shareIDHash string) error
|
||||
Update(shareIDHash string, fn func(*Record) error) error
|
||||
}
|
||||
Reference in new issue
Block a user