@@ -14,6 +14,7 @@ import (
1414 "code.gitea.io/gitea/modules/log"
1515 "code.gitea.io/gitea/modules/private"
1616 "code.gitea.io/gitea/modules/setting"
17+ repo_service "code.gitea.io/gitea/services/repository"
1718
1819 "gitea.com/macaron/macaron"
1920)
@@ -98,44 +99,44 @@ func ServCommand(ctx *macaron.Context) {
9899 }
99100
100101 // Now get the Repository and set the results section
102+ repoExist := true
101103 repo , err := models .GetRepositoryByOwnerAndName (results .OwnerName , results .RepoName )
102104 if err != nil {
103105 if models .IsErrRepoNotExist (err ) {
104- ctx .JSON (http .StatusNotFound , map [string ]interface {}{
106+ repoExist = false
107+ } else {
108+ log .Error ("Unable to get repository: %s/%s Error: %v" , results .OwnerName , results .RepoName , err )
109+ ctx .JSON (http .StatusInternalServerError , map [string ]interface {}{
105110 "results" : results ,
106- "type" : "ErrRepoNotExist " ,
107- "err" : fmt .Sprintf ("Cannot find repository %s/%s" , results .OwnerName , results .RepoName ),
111+ "type" : "InternalServerError " ,
112+ "err" : fmt .Sprintf ("Unable to get repository: %s/%s %v " , results .OwnerName , results .RepoName , err ),
108113 })
109114 return
110115 }
111- log .Error ("Unable to get repository: %s/%s Error: %v" , results .OwnerName , results .RepoName , err )
112- ctx .JSON (http .StatusInternalServerError , map [string ]interface {}{
113- "results" : results ,
114- "type" : "InternalServerError" ,
115- "err" : fmt .Sprintf ("Unable to get repository: %s/%s %v" , results .OwnerName , results .RepoName , err ),
116- })
117- return
118116 }
119- repo .OwnerName = ownerName
120- results .RepoID = repo .ID
121117
122- if repo .IsBeingCreated () {
123- ctx .JSON (http .StatusInternalServerError , map [string ]interface {}{
124- "results" : results ,
125- "type" : "InternalServerError" ,
126- "err" : "Repository is being created, you could retry after it finished" ,
127- })
128- return
129- }
118+ if repoExist {
119+ repo .OwnerName = ownerName
120+ results .RepoID = repo .ID
130121
131- // We can shortcut at this point if the repo is a mirror
132- if mode > models .AccessModeRead && repo .IsMirror {
133- ctx .JSON (http .StatusUnauthorized , map [string ]interface {}{
134- "results" : results ,
135- "type" : "ErrMirrorReadOnly" ,
136- "err" : fmt .Sprintf ("Mirror Repository %s/%s is read-only" , results .OwnerName , results .RepoName ),
137- })
138- return
122+ if repo .IsBeingCreated () {
123+ ctx .JSON (http .StatusInternalServerError , map [string ]interface {}{
124+ "results" : results ,
125+ "type" : "InternalServerError" ,
126+ "err" : "Repository is being created, you could retry after it finished" ,
127+ })
128+ return
129+ }
130+
131+ // We can shortcut at this point if the repo is a mirror
132+ if mode > models .AccessModeRead && repo .IsMirror {
133+ ctx .JSON (http .StatusUnauthorized , map [string ]interface {}{
134+ "results" : results ,
135+ "type" : "ErrMirrorReadOnly" ,
136+ "err" : fmt .Sprintf ("Mirror Repository %s/%s is read-only" , results .OwnerName , results .RepoName ),
137+ })
138+ return
139+ }
139140 }
140141
141142 // Get the Public Key represented by the keyID
@@ -161,6 +162,16 @@ func ServCommand(ctx *macaron.Context) {
161162 results .KeyID = key .ID
162163 results .UserID = key .OwnerID
163164
165+ // If repo doesn't exist, deploy key doesn't make sense
166+ if ! repoExist && key .Type == models .KeyTypeDeploy {
167+ ctx .JSON (http .StatusNotFound , map [string ]interface {}{
168+ "results" : results ,
169+ "type" : "ErrRepoNotExist" ,
170+ "err" : fmt .Sprintf ("Cannot find repository %s/%s" , results .OwnerName , results .RepoName ),
171+ })
172+ return
173+ }
174+
164175 // Deploy Keys have ownerID set to 0 therefore we can't use the owner
165176 // So now we need to check if the key is a deploy key
166177 // We'll keep hold of the deploy key here for permissions checking
@@ -220,7 +231,7 @@ func ServCommand(ctx *macaron.Context) {
220231 }
221232
222233 // Don't allow pushing if the repo is archived
223- if mode > models .AccessModeRead && repo .IsArchived {
234+ if repoExist && mode > models .AccessModeRead && repo .IsArchived {
224235 ctx .JSON (http .StatusUnauthorized , map [string ]interface {}{
225236 "results" : results ,
226237 "type" : "ErrRepoIsArchived" ,
@@ -230,7 +241,7 @@ func ServCommand(ctx *macaron.Context) {
230241 }
231242
232243 // Permissions checking:
233- if mode > models .AccessModeRead || repo .IsPrivate || setting .Service .RequireSignInView {
244+ if repoExist && ( mode > models .AccessModeRead || repo .IsPrivate || setting .Service .RequireSignInView ) {
234245 if key .Type == models .KeyTypeDeploy {
235246 if deployKey .Mode < mode {
236247 ctx .JSON (http .StatusUnauthorized , map [string ]interface {}{
@@ -265,6 +276,48 @@ func ServCommand(ctx *macaron.Context) {
265276 }
266277 }
267278
279+ // We already know we aren't using a deploy key
280+ if ! repoExist {
281+ owner , err := models .GetUserByName (ownerName )
282+ if err != nil {
283+ ctx .JSON (http .StatusInternalServerError , map [string ]interface {}{
284+ "results" : results ,
285+ "type" : "InternalServerError" ,
286+ "err" : fmt .Sprintf ("Unable to get owner: %s %v" , results .OwnerName , err ),
287+ })
288+ return
289+ }
290+
291+ if owner .IsOrganization () && ! setting .Repository .EnablePushCreateOrg {
292+ ctx .JSON (http .StatusForbidden , map [string ]interface {}{
293+ "results" : results ,
294+ "type" : "ErrForbidden" ,
295+ "err" : "Push to create is not enabled for organizations." ,
296+ })
297+ return
298+ }
299+ if ! owner .IsOrganization () && ! setting .Repository .EnablePushCreateUser {
300+ ctx .JSON (http .StatusForbidden , map [string ]interface {}{
301+ "results" : results ,
302+ "type" : "ErrForbidden" ,
303+ "err" : "Push to create is not enabled for users." ,
304+ })
305+ return
306+ }
307+
308+ repo , err = repo_service .PushCreateRepo (user , owner , results .RepoName )
309+ if err != nil {
310+ log .Error ("pushCreateRepo: %v" , err )
311+ ctx .JSON (http .StatusNotFound , map [string ]interface {}{
312+ "results" : results ,
313+ "type" : "ErrRepoNotExist" ,
314+ "err" : fmt .Sprintf ("Cannot find repository: %s/%s" , results .OwnerName , results .RepoName ),
315+ })
316+ return
317+ }
318+ results .RepoID = repo .ID
319+ }
320+
268321 // Finally if we're trying to touch the wiki we should init it
269322 if results .IsWiki {
270323 if err = repo .InitWiki (); err != nil {
0 commit comments