mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-25 23:33:08 +00:00
Fix agent auth (#1952)
if no global agent secret set, disable agent registration via it
This commit is contained in:
@@ -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)
|
|
||||||
}
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user