forked from leg100/otf
/
lock_service.go
87 lines (79 loc) · 2.23 KB
/
lock_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package workspace
import (
"context"
"fmt"
"github.com/tofutf/tofutf/internal/rbac"
"github.com/tofutf/tofutf/internal/user"
)
// Lock locks the workspace. A workspace can only be locked on behalf of a run or a
// user. If the former then runID must be populated. Otherwise a user is
// extracted from the context.
func (s *Service) Lock(ctx context.Context, workspaceID string, runID *string) (*Workspace, error) {
var (
id string
kind LockKind
)
if runID != nil {
id = *runID
kind = RunLock
} else {
subject, err := s.CanAccess(ctx, rbac.LockWorkspaceAction, workspaceID)
if err != nil {
return nil, err
}
user, ok := subject.(*user.User)
if !ok {
return nil, fmt.Errorf("only a run or a user can lock a workspace")
}
id = user.Username
kind = UserLock
}
ws, err := s.db.toggleLock(ctx, workspaceID, func(ws *Workspace) error {
return ws.Enlock(id, kind)
})
if err != nil {
s.Error(err, "locking workspace", "subject", id, "workspace", workspaceID)
return nil, err
}
s.V(1).Info("locked workspace", "subject", id, "workspace", workspaceID)
return ws, nil
}
// Unlock unlocks the workspace. A workspace can only be unlocked on behalf of a run or
// a user. If the former then runID must be non-nil; otherwise a user is
// extracted from the context.
func (s *Service) Unlock(ctx context.Context, workspaceID string, runID *string, force bool) (*Workspace, error) {
var (
id string
kind LockKind
)
if runID != nil {
id = *runID
kind = RunLock
} else {
var action rbac.Action
if force {
action = rbac.ForceUnlockWorkspaceAction
} else {
action = rbac.UnlockWorkspaceAction
}
subject, err := s.CanAccess(ctx, action, workspaceID)
if err != nil {
return nil, err
}
user, ok := subject.(*user.User)
if !ok {
return nil, fmt.Errorf("only a run or a user can unlock a workspace")
}
id = user.Username
kind = UserLock
}
ws, err := s.db.toggleLock(ctx, workspaceID, func(ws *Workspace) error {
return ws.Unlock(id, kind, force)
})
if err != nil {
s.Error(err, "unlocking workspace", "subject", id, "workspace", workspaceID, "forced", force)
return nil, err
}
s.V(1).Info("unlocked workspace", "subject", id, "workspace", workspaceID, "forced", force)
return ws, nil
}