From ee0097f97d80d0fe0e5fe1cb5ff4570a6a985373 Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Fri, 13 Nov 2020 09:28:32 +0800
Subject: [PATCH] Prevent git operations for inactive users (#13527) (#13536)

* prevent git operations for inactive users

* Some fixes

* Deny push to the repositories which's owner is inactive

* deny operations also when user is ProhibitLogin

Co-authored-by: zeripath <art27@cantab.net>

Co-authored-by: zeripath <art27@cantab.net>
---
 routers/private/serv.go | 45 ++++++++++++++++++++++++++++++++---------
 routers/repo/http.go    |  9 +++++++++
 2 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/routers/private/serv.go b/routers/private/serv.go
index 79683c2826..2697666b87 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -61,6 +61,12 @@ func ServNoCommand(ctx *macaron.Context) {
 			})
 			return
 		}
+		if !user.IsActive || user.ProhibitLogin {
+			ctx.JSON(http.StatusForbidden, map[string]interface{}{
+				"err": "Your account is disabled.",
+			})
+			return
+		}
 		results.Owner = user
 	}
 	ctx.JSON(http.StatusOK, &results)
@@ -98,9 +104,28 @@ func ServCommand(ctx *macaron.Context) {
 		results.RepoName = repoName[:len(repoName)-5]
 	}
 
+	owner, err := models.GetUserByName(results.OwnerName)
+	if err != nil {
+		log.Error("Unable to get repository owner: %s/%s Error: %v", results.OwnerName, results.RepoName, err)
+		ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
+			"results": results,
+			"type":    "InternalServerError",
+			"err":     fmt.Sprintf("Unable to get repository owner: %s/%s %v", results.OwnerName, results.RepoName, err),
+		})
+		return
+	}
+	if !owner.IsActive {
+		ctx.JSON(http.StatusForbidden, map[string]interface{}{
+			"results": results,
+			"type":    "ForbiddenError",
+			"err":     "Repository cannot be accessed, you could retry it later",
+		})
+		return
+	}
+
 	// Now get the Repository and set the results section
 	repoExist := true
-	repo, err := models.GetRepositoryByOwnerAndName(results.OwnerName, results.RepoName)
+	repo, err := models.GetRepositoryByName(owner.ID, results.RepoName)
 	if err != nil {
 		if models.IsErrRepoNotExist(err) {
 			repoExist = false
@@ -127,6 +152,7 @@ func ServCommand(ctx *macaron.Context) {
 	}
 
 	if repoExist {
+		repo.Owner = owner
 		repo.OwnerName = ownerName
 		results.RepoID = repo.ID
 
@@ -217,15 +243,6 @@ func ServCommand(ctx *macaron.Context) {
 		// so for now use the owner of the repository
 		results.UserName = results.OwnerName
 		results.UserID = repo.OwnerID
-		if err = repo.GetOwner(); err != nil {
-			log.Error("Unable to get owner for repo %-v. Error: %v", repo, err)
-			ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
-				"results": results,
-				"type":    "InternalServerError",
-				"err":     fmt.Sprintf("Unable to get owner for repo: %s/%s.", results.OwnerName, results.RepoName),
-			})
-			return
-		}
 		if !repo.Owner.KeepEmailPrivate {
 			results.UserEmail = repo.Owner.Email
 		}
@@ -250,6 +267,14 @@ func ServCommand(ctx *macaron.Context) {
 			})
 			return
 		}
+
+		if !user.IsActive || user.ProhibitLogin {
+			ctx.JSON(http.StatusForbidden, map[string]interface{}{
+				"err": "Your account is disabled.",
+			})
+			return
+		}
+
 		results.UserName = user.Name
 		if !user.KeepEmailPrivate {
 			results.UserEmail = user.Email
diff --git a/routers/repo/http.go b/routers/repo/http.go
index 23f2665dfd..1de5dd9a93 100644
--- a/routers/repo/http.go
+++ b/routers/repo/http.go
@@ -105,6 +105,10 @@ func HTTP(ctx *context.Context) {
 		ctx.NotFoundOrServerError("GetUserByName", models.IsErrUserNotExist, err)
 		return
 	}
+	if !owner.IsActive {
+		ctx.HandleText(http.StatusForbidden, "Repository cannot be accessed. You cannot push or open issues/pull-requests.")
+		return
+	}
 
 	repoExist := true
 	repo, err := models.GetRepositoryByName(owner.ID, reponame)
@@ -244,6 +248,11 @@ func HTTP(ctx *context.Context) {
 			}
 		}
 
+		if !authUser.IsActive || authUser.ProhibitLogin {
+			ctx.HandleText(http.StatusForbidden, "Your account is disabled.")
+			return
+		}
+
 		if repoExist {
 			perm, err := models.GetUserRepoPermission(repo, authUser)
 			if err != nil {