Fix agent auth (#1952)

if no global agent secret set, disable agent registration via it
This commit is contained in:
6543
2023-07-08 18:09:34 +02:00
committed by GitHub
parent cef135eba5
commit 6c58e9db9b
4 changed files with 41 additions and 28 deletions

View File

@@ -26,6 +26,7 @@ import (
"github.com/woodpecker-ci/woodpecker/server" "github.com/woodpecker-ci/woodpecker/server"
"github.com/woodpecker-ci/woodpecker/server/model" "github.com/woodpecker-ci/woodpecker/server/model"
"github.com/woodpecker-ci/woodpecker/server/router/middleware"
"github.com/woodpecker-ci/woodpecker/server/store" "github.com/woodpecker-ci/woodpecker/server/store"
"github.com/woodpecker-ci/woodpecker/server/store/types" "github.com/woodpecker-ci/woodpecker/server/store/types"
"github.com/woodpecker-ci/woodpecker/shared/httputil" "github.com/woodpecker-ci/woodpecker/shared/httputil"
@@ -63,7 +64,7 @@ func HandleAuth(c *gin.Context) {
if tmpuser == nil { if tmpuser == nil {
return return
} }
config := ToConfig(c) config := middleware.GetConfig(c)
// get the user from the database // get the user from the database
u, err := _store.GetUserRemoteID(tmpuser.ForgeRemoteID, tmpuser.Login) u, err := _store.GetUserRemoteID(tmpuser.ForgeRemoteID, tmpuser.Login)
@@ -227,9 +228,3 @@ type tokenPayload struct {
Refresh string `json:"refresh_token,omitempty"` Refresh string `json:"refresh_token,omitempty"`
Expires int64 `json:"expires_in,omitempty"` Expires int64 `json:"expires_in,omitempty"`
} }
// ToConfig returns the config from the Context
func ToConfig(c *gin.Context) *model.Settings {
v := c.MustGet("config")
return v.(*model.Settings)
}

View File

@@ -16,13 +16,15 @@ package grpc
import ( import (
"context" "context"
"errors"
"fmt"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/woodpecker-ci/woodpecker/pipeline/rpc/proto" "github.com/woodpecker-ci/woodpecker/pipeline/rpc/proto"
"github.com/woodpecker-ci/woodpecker/server"
"github.com/woodpecker-ci/woodpecker/server/model" "github.com/woodpecker-ci/woodpecker/server/model"
"github.com/woodpecker-ci/woodpecker/server/store" "github.com/woodpecker-ci/woodpecker/server/store"
"github.com/woodpecker-ci/woodpecker/server/store/types"
) )
type WoodpeckerAuthServer struct { type WoodpeckerAuthServer struct {
@@ -39,7 +41,7 @@ func NewWoodpeckerAuthServer(jwtManager *JWTManager, agentMasterToken string, st
func (s *WoodpeckerAuthServer) Auth(_ context.Context, req *proto.AuthRequest) (*proto.AuthResponse, error) { func (s *WoodpeckerAuthServer) Auth(_ context.Context, req *proto.AuthRequest) (*proto.AuthResponse, error) {
agent, err := s.getAgent(req.AgentId, req.AgentToken) agent, err := s.getAgent(req.AgentId, req.AgentToken)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("Agent could not auth: %w", err)
} }
accessToken, err := s.jwtManager.Generate(agent.ID) accessToken, err := s.jwtManager.Generate(agent.ID)
@@ -55,11 +57,13 @@ func (s *WoodpeckerAuthServer) Auth(_ context.Context, req *proto.AuthRequest) (
} }
func (s *WoodpeckerAuthServer) getAgent(agentID int64, agentToken string) (*model.Agent, error) { func (s *WoodpeckerAuthServer) getAgent(agentID int64, agentToken string) (*model.Agent, error) {
// global agent secret auth
if s.agentMasterToken != "" {
if agentToken == s.agentMasterToken && agentID == -1 { if agentToken == s.agentMasterToken && agentID == -1 {
agent := new(model.Agent) agent := new(model.Agent)
agent.Name = "" agent.Name = ""
agent.OwnerID = -1 // system agent agent.OwnerID = -1 // system agent
agent.Token = server.Config.Server.AgentToken agent.Token = s.agentMasterToken
agent.Backend = "" agent.Backend = ""
agent.Platform = "" agent.Platform = ""
agent.Capacity = -1 agent.Capacity = -1
@@ -72,8 +76,18 @@ func (s *WoodpeckerAuthServer) getAgent(agentID int64, agentToken string) (*mode
} }
if agentToken == s.agentMasterToken { if agentToken == s.agentMasterToken {
return s.store.AgentFind(agentID) agent, err := s.store.AgentFind(agentID)
if err != nil && errors.Is(err, types.RecordNotExist) {
return nil, fmt.Errorf("AgentID not found in database")
}
return agent, err
}
} }
return s.store.AgentFindByToken(agentToken) // individual agent token auth
agent, err := s.store.AgentFindByToken(agentToken)
if err != nil && errors.Is(err, types.RecordNotExist) {
return nil, fmt.Errorf("individual agent not found by token: %w", err)
}
return agent, err
} }

View File

@@ -17,7 +17,6 @@ package model
// Settings defines system configuration parameters. // Settings defines system configuration parameters.
type Settings struct { type Settings struct {
Open bool // Enables open registration Open bool // Enables open registration
Secret string // Secret token used to authenticate agents
Admins map[string]bool // Administrative users Admins map[string]bool // Administrative users
Orgs map[string]bool // Organization whitelist Orgs map[string]bool // Organization whitelist
OwnersWhitelist map[string]bool // Owners whitelist OwnersWhitelist map[string]bool // Owners whitelist

View File

@@ -36,7 +36,6 @@ func Config(cli *cli.Context) gin.HandlerFunc {
func setupConfig(c *cli.Context) *model.Settings { func setupConfig(c *cli.Context) *model.Settings {
return &model.Settings{ return &model.Settings{
Open: c.Bool("open"), Open: c.Bool("open"),
Secret: c.String("agent-secret"),
Admins: sliceToMap2(c.StringSlice("admin")), Admins: sliceToMap2(c.StringSlice("admin")),
Orgs: sliceToMap2(c.StringSlice("orgs")), Orgs: sliceToMap2(c.StringSlice("orgs")),
OwnersWhitelist: sliceToMap2(c.StringSlice("repo-owners")), OwnersWhitelist: sliceToMap2(c.StringSlice("repo-owners")),
@@ -54,3 +53,9 @@ func sliceToMap2(s []string) map[string]bool {
} }
return v return v
} }
// GetConfig returns the config from the Context
func GetConfig(c *gin.Context) *model.Settings {
v := c.MustGet(configKey)
return v.(*model.Settings)
}