mirror of
https://github.com/harness/drone.git
synced 2025-05-20 19:09:59 +08:00
[bug] authentication on push to public repo (#74)
* authentication on push to public repo * receivepack or uploadpack this should also be enum.PermissionRepoEdit or enum.PermissionRepoView * accountID used for realm
This commit is contained in:
parent
782c6f2bd7
commit
86716b4a0c
@ -6,10 +6,13 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/internal/paths"
|
||||||
|
|
||||||
"github.com/harness/gitness/gitrpc"
|
"github.com/harness/gitness/gitrpc"
|
||||||
apiauth "github.com/harness/gitness/internal/api/auth"
|
apiauth "github.com/harness/gitness/internal/api/auth"
|
||||||
"github.com/harness/gitness/internal/api/request"
|
"github.com/harness/gitness/internal/api/request"
|
||||||
@ -23,9 +26,13 @@ import (
|
|||||||
|
|
||||||
type CtxRepoType string
|
type CtxRepoType string
|
||||||
|
|
||||||
const (
|
type GitAuthError struct {
|
||||||
CtxRepoKey CtxRepoType = "repo"
|
AccountID string
|
||||||
)
|
}
|
||||||
|
|
||||||
|
func (e GitAuthError) Error() string {
|
||||||
|
return fmt.Sprintf("Authentication failed for account %s", e.AccountID)
|
||||||
|
}
|
||||||
|
|
||||||
func GetInfoRefs(client gitrpc.Interface, repoStore store.RepoStore, authorizer authz.Authorizer) http.HandlerFunc {
|
func GetInfoRefs(client gitrpc.Interface, repoStore store.RepoStore, authorizer authz.Authorizer) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -43,9 +50,17 @@ func GetInfoRefs(client gitrpc.Interface, repoStore store.RepoStore, authorizer
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accountID, _, err := paths.DisectRoot(repo.Path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err = apiauth.CheckRepo(ctx, authorizer, session, repo, enum.PermissionRepoView, true); err != nil {
|
if err = apiauth.CheckRepo(ctx, authorizer, session, repo, enum.PermissionRepoView, true); err != nil {
|
||||||
w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, repo.GitUID))
|
if errors.Is(err, apiauth.ErrNotAuthenticated) {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
basicAuth(w, accountID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +91,7 @@ func GetUploadPack(client gitrpc.Interface, repoStore store.RepoStore, authorize
|
|||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
const service = "upload-pack"
|
const service = "upload-pack"
|
||||||
|
|
||||||
if err := serviceRPC(w, r, client, repoStore, authorizer, service); err != nil {
|
if err := serviceRPC(w, r, client, repoStore, authorizer, service, enum.PermissionRepoView, true); err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -86,8 +101,12 @@ func GetUploadPack(client gitrpc.Interface, repoStore store.RepoStore, authorize
|
|||||||
func PostReceivePack(client gitrpc.Interface, repoStore store.RepoStore, authorizer authz.Authorizer) http.HandlerFunc {
|
func PostReceivePack(client gitrpc.Interface, repoStore store.RepoStore, authorizer authz.Authorizer) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
const service = "receive-pack"
|
const service = "receive-pack"
|
||||||
|
if err := serviceRPC(w, r, client, repoStore, authorizer, service, enum.PermissionRepoEdit, false); err != nil {
|
||||||
if err := serviceRPC(w, r, client, repoStore, authorizer, service); err != nil {
|
var authError *GitAuthError
|
||||||
|
if errors.As(err, &authError) {
|
||||||
|
basicAuth(w, authError.AccountID)
|
||||||
|
return
|
||||||
|
}
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -101,6 +120,8 @@ func serviceRPC(
|
|||||||
repoStore store.RepoStore,
|
repoStore store.RepoStore,
|
||||||
authorizer authz.Authorizer,
|
authorizer authz.Authorizer,
|
||||||
service string,
|
service string,
|
||||||
|
permission enum.Permission,
|
||||||
|
orPublic bool,
|
||||||
) error {
|
) error {
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
log := hlog.FromRequest(r)
|
log := hlog.FromRequest(r)
|
||||||
@ -121,7 +142,17 @@ func serviceRPC(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = apiauth.CheckRepo(ctx, authorizer, session, repo, enum.PermissionRepoEdit, true); err != nil {
|
accountID, _, err := paths.DisectRoot(repo.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = apiauth.CheckRepo(ctx, authorizer, session, repo, permission, orPublic); err != nil {
|
||||||
|
if errors.Is(err, apiauth.ErrNotAuthenticated) {
|
||||||
|
return &GitAuthError{
|
||||||
|
AccountID: accountID,
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,14 +167,17 @@ func serviceRPC(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return client.ServicePack(ctx, w, &gitrpc.ServicePackParams{
|
params := &gitrpc.ServicePackParams{
|
||||||
RepoUID: repo.GitUID,
|
RepoUID: repo.GitUID,
|
||||||
Service: service,
|
Service: service,
|
||||||
Data: reqBody,
|
Data: reqBody,
|
||||||
Options: nil,
|
Options: nil,
|
||||||
PrincipalID: session.Principal.ID,
|
|
||||||
GitProtocol: r.Header.Get("Git-Protocol"),
|
GitProtocol: r.Header.Get("Git-Protocol"),
|
||||||
})
|
}
|
||||||
|
if session != nil {
|
||||||
|
params.PrincipalID = session.Principal.ID
|
||||||
|
}
|
||||||
|
return client.ServicePack(ctx, w, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setHeaderNoCache(w http.ResponseWriter) {
|
func setHeaderNoCache(w http.ResponseWriter) {
|
||||||
@ -159,3 +193,8 @@ func getServiceType(r *http.Request) string {
|
|||||||
}
|
}
|
||||||
return strings.Replace(serviceType, "git-", "", 1)
|
return strings.Replace(serviceType, "git-", "", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func basicAuth(w http.ResponseWriter, accountID string) {
|
||||||
|
w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, accountID))
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user