Diff
1diff --git a/pkg/web/git_lfs.go b/pkg/web/git_lfs.go
2index 72b37e88c9bd93773dd338bebceb2832a8f01b57..cc109107312891630b8f3c3884ec33bba9c0d2f9 100644
3--- a/pkg/web/git_lfs.go
4+++ b/pkg/web/git_lfs.go
5@@ -893,7 +893,6 @@ func serviceLfsLocksDelete(w http.ResponseWriter, r *http.Request) {
6 return
7 }
8
9- // Delete another user's lock
10 l := lfs.Lock{
11 ID: strconv.FormatInt(lock.ID, 10),
12 Path: lock.Path,
13@@ -902,7 +901,27 @@ func serviceLfsLocksDelete(w http.ResponseWriter, r *http.Request) {
14 Name: owner.Username,
15 },
16 }
17+
18+ // Retrieve user context first for authorization checks
19+ user := proto.UserFromContext(ctx)
20+ if user == nil {
21+ logger.Error("error getting user from context")
22+ renderJSON(w, http.StatusUnauthorized, lfs.ErrorResponse{
23+ Message: "unauthorized",
24+ })
25+ return
26+ }
27+
28+ // Force delete another user's lock (requires admin privileges)
29 if req.Force {
30+ if !user.IsAdmin() {
31+ logger.Error("non-admin user attempted force delete", "user", user.Username())
32+ renderJSON(w, http.StatusForbidden, lfs.ErrorResponse{
33+ Message: "admin access required for force delete",
34+ })
35+ return
36+ }
37+
38 if err := datastore.DeleteLFSLock(ctx, dbx, repo.ID(), lockID); err != nil {
39 logger.Error("error deleting lock", "err", err)
40 renderJSON(w, http.StatusInternalServerError, lfs.ErrorResponse{
41@@ -915,16 +934,7 @@ func serviceLfsLocksDelete(w http.ResponseWriter, r *http.Request) {
42 return
43 }
44
45- // Delete our own lock
46- user := proto.UserFromContext(ctx)
47- if user == nil {
48- logger.Error("error getting user from context")
49- renderJSON(w, http.StatusUnauthorized, lfs.ErrorResponse{
50- Message: "unauthorized",
51- })
52- return
53- }
54-
55+ // Delete our own lock - verify ownership
56 if owner.ID != user.ID() {
57 logger.Error("error deleting another user's lock")
58 renderJSON(w, http.StatusForbidden, lfs.ErrorResponse{