Browse Source

Fix Git LFS object/repo link storage in database and small refactoring (#2803)

Lauris BH 1 year ago
parent
commit
82fc50f4ee
2 changed files with 38 additions and 59 deletions
  1. 4 5
      models/lfs.go
  2. 34 54
      modules/lfs/server.go

+ 4 - 5
models/lfs.go

@@ -70,12 +70,12 @@ func NewLFSMetaObject(m *LFSMetaObject) (*LFSMetaObject, error) {
70 70
 // GetLFSMetaObjectByOid selects a LFSMetaObject entry from database by its OID.
71 71
 // It may return ErrLFSObjectNotExist or a database error. If the error is nil,
72 72
 // the returned pointer is a valid LFSMetaObject.
73
-func GetLFSMetaObjectByOid(oid string) (*LFSMetaObject, error) {
73
+func (repo *Repository) GetLFSMetaObjectByOid(oid string) (*LFSMetaObject, error) {
74 74
 	if len(oid) == 0 {
75 75
 		return nil, ErrLFSObjectNotExist
76 76
 	}
77 77
 
78
-	m := &LFSMetaObject{Oid: oid}
78
+	m := &LFSMetaObject{Oid: oid, RepositoryID: repo.ID}
79 79
 	has, err := x.Get(m)
80 80
 	if err != nil {
81 81
 		return nil, err
@@ -87,7 +87,7 @@ func GetLFSMetaObjectByOid(oid string) (*LFSMetaObject, error) {
87 87
 
88 88
 // RemoveLFSMetaObjectByOid removes a LFSMetaObject entry from database by its OID.
89 89
 // It may return ErrLFSObjectNotExist or a database error.
90
-func RemoveLFSMetaObjectByOid(oid string) error {
90
+func (repo *Repository) RemoveLFSMetaObjectByOid(oid string) error {
91 91
 	if len(oid) == 0 {
92 92
 		return ErrLFSObjectNotExist
93 93
 	}
@@ -98,8 +98,7 @@ func RemoveLFSMetaObjectByOid(oid string) error {
98 98
 		return err
99 99
 	}
100 100
 
101
-	m := &LFSMetaObject{Oid: oid}
102
-
101
+	m := &LFSMetaObject{Oid: oid, RepositoryID: repo.ID}
103 102
 	if _, err := sess.Delete(m); err != nil {
104 103
 		return err
105 104
 	}

+ 34 - 54
modules/lfs/server.go

@@ -86,11 +86,11 @@ func ObjectOidHandler(ctx *context.Context) {
86 86
 
87 87
 	if ctx.Req.Method == "GET" || ctx.Req.Method == "HEAD" {
88 88
 		if MetaMatcher(ctx.Req) {
89
-			GetMetaHandler(ctx)
89
+			getMetaHandler(ctx)
90 90
 			return
91 91
 		}
92 92
 		if ContentMatcher(ctx.Req) || len(ctx.Params("filename")) > 0 {
93
-			GetContentHandler(ctx)
93
+			getContentHandler(ctx)
94 94
 			return
95 95
 		}
96 96
 	} else if ctx.Req.Method == "PUT" && ContentMatcher(ctx.Req) {
@@ -100,26 +100,35 @@ func ObjectOidHandler(ctx *context.Context) {
100 100
 
101 101
 }
102 102
 
103
-// GetContentHandler gets the content from the content store
104
-func GetContentHandler(ctx *context.Context) {
105
-
106
-	rv := unpack(ctx)
107
-
108
-	meta, err := models.GetLFSMetaObjectByOid(rv.Oid)
103
+func getAuthenticatedRepoAndMeta(ctx *context.Context, rv *RequestVars, requireWrite bool) (*models.LFSMetaObject, *models.Repository) {
104
+	repositoryString := rv.User + "/" + rv.Repo
105
+	repository, err := models.GetRepositoryByRef(repositoryString)
109 106
 	if err != nil {
107
+		log.Debug("Could not find repository: %s - %s", repositoryString, err)
110 108
 		writeStatus(ctx, 404)
111
-		return
109
+		return nil, nil
112 110
 	}
113 111
 
114
-	repository, err := models.GetRepositoryByID(meta.RepositoryID)
112
+	if !authenticate(ctx, repository, rv.Authorization, requireWrite) {
113
+		requireAuth(ctx)
114
+		return nil, nil
115
+	}
115 116
 
117
+	meta, err := repository.GetLFSMetaObjectByOid(rv.Oid)
116 118
 	if err != nil {
117 119
 		writeStatus(ctx, 404)
118
-		return
120
+		return nil, nil
119 121
 	}
120 122
 
121
-	if !authenticate(ctx, repository, rv.Authorization, false) {
122
-		requireAuth(ctx)
123
+	return meta, repository
124
+}
125
+
126
+// getContentHandler gets the content from the content store
127
+func getContentHandler(ctx *context.Context) {
128
+	rv := unpack(ctx)
129
+
130
+	meta, _ := getAuthenticatedRepoAndMeta(ctx, rv, false)
131
+	if meta == nil {
123 132
 		return
124 133
 	}
125 134
 
@@ -160,26 +169,12 @@ func GetContentHandler(ctx *context.Context) {
160 169
 	logRequest(ctx.Req, statusCode)
161 170
 }
162 171
 
163
-// GetMetaHandler retrieves metadata about the object
164
-func GetMetaHandler(ctx *context.Context) {
165
-
172
+// getMetaHandler retrieves metadata about the object
173
+func getMetaHandler(ctx *context.Context) {
166 174
 	rv := unpack(ctx)
167 175
 
168
-	meta, err := models.GetLFSMetaObjectByOid(rv.Oid)
169
-	if err != nil {
170
-		writeStatus(ctx, 404)
171
-		return
172
-	}
173
-
174
-	repository, err := models.GetRepositoryByID(meta.RepositoryID)
175
-
176
-	if err != nil {
177
-		writeStatus(ctx, 404)
178
-		return
179
-	}
180
-
181
-	if !authenticate(ctx, repository, rv.Authorization, false) {
182
-		requireAuth(ctx)
176
+	meta, _ := getAuthenticatedRepoAndMeta(ctx, rv, false)
177
+	if meta == nil {
183 178
 		return
184 179
 	}
185 180
 
@@ -210,7 +205,6 @@ func PostHandler(ctx *context.Context) {
210 205
 
211 206
 	repositoryString := rv.User + "/" + rv.Repo
212 207
 	repository, err := models.GetRepositoryByRef(repositoryString)
213
-
214 208
 	if err != nil {
215 209
 		log.Debug("Could not find repository: %s - %s", repositoryString, err)
216 210
 		writeStatus(ctx, 404)
@@ -222,7 +216,6 @@ func PostHandler(ctx *context.Context) {
222 216
 	}
223 217
 
224 218
 	meta, err := models.NewLFSMetaObject(&models.LFSMetaObject{Oid: rv.Oid, Size: rv.Size, RepositoryID: repository.ID})
225
-
226 219
 	if err != nil {
227 220
 		writeStatus(ctx, 404)
228 221
 		return
@@ -281,9 +274,9 @@ func BatchHandler(ctx *context.Context) {
281 274
 			return
282 275
 		}
283 276
 
284
-		meta, err := models.GetLFSMetaObjectByOid(object.Oid)
285
-
286 277
 		contentStore := &ContentStore{BasePath: setting.LFS.ContentPath}
278
+
279
+		meta, err := repository.GetLFSMetaObjectByOid(object.Oid)
287 280
 		if err == nil && contentStore.Exists(meta) { // Object is found and exists
288 281
 			responseObjects = append(responseObjects, Represent(object, meta, true, false))
289 282
 			continue
@@ -291,9 +284,8 @@ func BatchHandler(ctx *context.Context) {
291 284
 
292 285
 		// Object is not found
293 286
 		meta, err = models.NewLFSMetaObject(&models.LFSMetaObject{Oid: object.Oid, Size: object.Size, RepositoryID: repository.ID})
294
-
295 287
 		if err == nil {
296
-			responseObjects = append(responseObjects, Represent(object, meta, meta.Existing, true))
288
+			responseObjects = append(responseObjects, Represent(object, meta, meta.Existing, !contentStore.Exists(meta)))
297 289
 		}
298 290
 	}
299 291
 
@@ -310,30 +302,18 @@ func BatchHandler(ctx *context.Context) {
310 302
 func PutHandler(ctx *context.Context) {
311 303
 	rv := unpack(ctx)
312 304
 
313
-	meta, err := models.GetLFSMetaObjectByOid(rv.Oid)
314
-
315
-	if err != nil {
316
-		writeStatus(ctx, 404)
317
-		return
318
-	}
319
-
320
-	repository, err := models.GetRepositoryByID(meta.RepositoryID)
321
-
322
-	if err != nil {
323
-		writeStatus(ctx, 404)
324
-		return
325
-	}
326
-
327
-	if !authenticate(ctx, repository, rv.Authorization, true) {
328
-		requireAuth(ctx)
305
+	meta, repository := getAuthenticatedRepoAndMeta(ctx, rv, true)
306
+	if meta == nil {
329 307
 		return
330 308
 	}
331 309
 
332 310
 	contentStore := &ContentStore{BasePath: setting.LFS.ContentPath}
333 311
 	if err := contentStore.Put(meta, ctx.Req.Body().ReadCloser()); err != nil {
334
-		models.RemoveLFSMetaObjectByOid(rv.Oid)
335 312
 		ctx.Resp.WriteHeader(500)
336 313
 		fmt.Fprintf(ctx.Resp, `{"message":"%s"}`, err)
314
+		if err = repository.RemoveLFSMetaObjectByOid(rv.Oid); err != nil {
315
+			log.Error(4, "RemoveLFSMetaObjectByOid: %v", err)
316
+		}
337 317
 		return
338 318
 	}
339 319