Skip to content

Commit

Permalink
fix(api): use consumer name instead of username if service or worker (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored and fsamin committed Jan 23, 2020
1 parent d9a2517 commit c4f892c
Show file tree
Hide file tree
Showing 18 changed files with 199 additions and 192 deletions.
78 changes: 24 additions & 54 deletions engine/api/api_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (

"github.com/ovh/cds/engine/api/group"
"github.com/ovh/cds/engine/api/services"
"github.com/ovh/cds/engine/api/worker"
"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/log"
)
Expand Down Expand Up @@ -52,6 +51,30 @@ func isAdmin(ctx context.Context) bool {
return c.Admin()
}

func isService(ctx context.Context) bool {
c := getAPIConsumer(ctx)
if c == nil {
return false
}
return c.Service != nil
}

func isWorker(ctx context.Context) bool {
c := getAPIConsumer(ctx)
if c == nil {
return false
}
return c.Worker != nil
}

func isHatchery(ctx context.Context) bool {
c := getAPIConsumer(ctx)
if c == nil {
return false
}
return c.Service != nil && c.Service.Type == services.TypeHatchery
}

func getAPIConsumer(c context.Context) *sdk.AuthConsumer {
i := c.Value(contextAPIConsumer)
if i == nil {
Expand Down Expand Up @@ -108,56 +131,3 @@ func (a *API) mustDBWithCtx(ctx context.Context) *gorp.DbMap {

return db
}

func (a *API) isService(ctx context.Context) (*sdk.Service, bool) {
db := a.mustDBWithCtx(ctx)
session := getAuthSession(ctx)
if session == nil {
return nil, false
}

s, err := services.LoadByConsumerID(ctx, db, session.ConsumerID)
if err != nil {
log.Info(ctx, "unable to get service from session %s: %v", session.ID, err)
return nil, false
}
return s, true
}

func (a *API) isWorker(ctx context.Context) (*sdk.Worker, bool) {
db := a.mustDBWithCtx(ctx)
s := getAuthSession(ctx)
if s == nil {
return nil, false
}
w, err := worker.LoadByConsumerID(ctx, db, s.ConsumerID)
if sdk.ErrorIs(err, sdk.ErrNotFound) {
return nil, false
}
if err != nil {
log.Warning(ctx, "unable to get worker from session %s: %v", s.ID, err)
return nil, false
}
if w == nil {
return nil, false
}
return w, true
}

func (a *API) isHatchery(ctx context.Context) (*sdk.Service, bool) {
db := a.mustDBWithCtx(ctx)
session := getAuthSession(ctx)
if session == nil {
return nil, false
}

s, err := services.LoadByConsumerID(ctx, db, session.ConsumerID)
if err != nil {
log.Warning(ctx, "unable to get hatchery from session %s: %v", session.ID, err)
return nil, false
}
if s.Type != services.TypeHatchery {
return nil, false
}
return s, true
}
17 changes: 9 additions & 8 deletions engine/api/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func (api *API) postPushCacheHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
if _, isWorker := api.isWorker(ctx); !isWorker {
if isWorker := isWorker(ctx); !isWorker {
return sdk.WithStack(sdk.ErrForbidden)
}

Expand All @@ -24,11 +24,11 @@ func (api *API) postPushCacheHandler() service.Handler {
// check tag name pattern
regexp := sdk.NamePatternRegex
if !regexp.MatchString(tag) {
return sdk.ErrInvalidName
return sdk.WithStack(sdk.ErrInvalidName)
}

if r.Body == nil {
return sdk.ErrWrongRequest
return sdk.WithStack(sdk.ErrWrongRequest)
}
defer r.Body.Close()

Expand All @@ -44,7 +44,7 @@ func (api *API) postPushCacheHandler() service.Handler {
}

if _, err := storageDriver.Store(&cacheObject, r.Body); err != nil {
return sdk.WrapError(err, "postPushCacheHandler>Cannot store cache")
return sdk.WrapError(err, "cannot store cache")
}

return nil
Expand All @@ -53,7 +53,7 @@ func (api *API) postPushCacheHandler() service.Handler {

func (api *API) getPullCacheHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
if _, isWorker := api.isWorker(ctx); !isWorker {
if isWorker := isWorker(ctx); !isWorker {
return sdk.WithStack(sdk.ErrForbidden)
}

Expand All @@ -63,7 +63,7 @@ func (api *API) getPullCacheHandler() service.Handler {
// check tag name pattern
regexp := sdk.NamePatternRegex
if !regexp.MatchString(tag) {
return sdk.ErrInvalidName
return sdk.WithStack(sdk.ErrInvalidName)
}

cacheObject := sdk.Cache{
Expand Down Expand Up @@ -101,13 +101,14 @@ func (api *API) getPullCacheHandler() service.Handler {
if err := ioread.Close(); err != nil {
return sdk.WrapError(err, "cannot close artifact")
}

return nil
}
}

func (api *API) postPushCacheWithTempURLHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
if _, isWorker := api.isWorker(ctx); !isWorker {
if isWorker := isWorker(ctx); !isWorker {
return sdk.WithStack(sdk.ErrForbidden)
}

Expand Down Expand Up @@ -149,7 +150,7 @@ func (api *API) postPushCacheWithTempURLHandler() service.Handler {

func (api *API) getPullCacheWithTempURLHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
if _, isWorker := api.isWorker(ctx); !isWorker {
if isWorker := isWorker(ctx); !isWorker {
return sdk.WithStack(sdk.ErrForbidden)
}

Expand Down
27 changes: 7 additions & 20 deletions engine/api/navbar/navbar.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,12 @@ import (

"github.com/go-gorp/gorp"

"github.com/ovh/cds/engine/api/cache"
"github.com/ovh/cds/engine/api/database/gorpmapping"
"github.com/ovh/cds/engine/api/group"
"github.com/ovh/cds/sdk"
)

// LoadNavbarData returns just the needed data for the ui navbar
func LoadNavbarData(db gorp.SqlExecutor, store cache.Store, u sdk.AuthentifiedUser) (data []sdk.NavbarProjectData, err error) {
// Admin can gets all project
// Users can gets only their projects

if u.Admin() {
return loadNavbarAsAdmin(db, store, u)
}

return loadNavbarAsUser(db, store, u)
}

func loadNavbarAsAdmin(db gorp.SqlExecutor, store cache.Store, u sdk.AuthentifiedUser) (data []sdk.NavbarProjectData, err error) {
func LoadNavbarAsAdmin(db gorp.SqlExecutor, userID int64) (data []sdk.NavbarProjectData, err error) {
query := `
(
SELECT DISTINCT
Expand Down Expand Up @@ -61,9 +48,9 @@ func loadNavbarAsAdmin(db gorp.SqlExecutor, store cache.Store, u sdk.Authentifie
)
`

rows, err := db.Query(query, u.OldUserStruct.ID)
rows, err := db.Query(query, userID)
if err != nil {
return data, err
return data, sdk.WithStack(err)
}
defer rows.Close()

Expand All @@ -72,7 +59,7 @@ func loadNavbarAsAdmin(db gorp.SqlExecutor, store cache.Store, u sdk.Authentifie
var favorite bool
var name sql.NullString
if err := rows.Scan(&key, &projectName, &projectDescription, &name, &favorite, &eltType); err != nil {
return data, err
return data, sdk.WithStack(err)
}

projData := sdk.NavbarProjectData{
Expand All @@ -98,7 +85,7 @@ func loadNavbarAsAdmin(db gorp.SqlExecutor, store cache.Store, u sdk.Authentifie
return data, nil
}

func loadNavbarAsUser(db gorp.SqlExecutor, store cache.Store, u sdk.AuthentifiedUser) (data []sdk.NavbarProjectData, err error) {
func LoadNavbarAsUser(db gorp.SqlExecutor, userID int64, groupIDs []int64) (data []sdk.NavbarProjectData, err error) {
query := `
(
SELECT DISTINCT
Expand Down Expand Up @@ -160,7 +147,7 @@ func loadNavbarAsUser(db gorp.SqlExecutor, store cache.Store, u sdk.Authentified
)
`

rows, err := db.Query(query, u.OldUserStruct.ID, gorpmapping.IDsToQueryString(u.OldUserStruct.Groups.ToIDs()), group.SharedInfraGroup.ID)
rows, err := db.Query(query, userID, gorpmapping.IDsToQueryString(groupIDs), group.SharedInfraGroup.ID)
if err != nil {
return data, sdk.WithStack(err)
}
Expand All @@ -171,7 +158,7 @@ func loadNavbarAsUser(db gorp.SqlExecutor, store cache.Store, u sdk.Authentified
var favorite bool
var name sql.NullString
if err := rows.Scan(&key, &projectName, &projectDescription, &name, &favorite, &eltType); err != nil {
return data, err
return data, sdk.WithStack(err)
}

projData := sdk.NavbarProjectData{
Expand Down
18 changes: 18 additions & 0 deletions engine/api/router_middleware_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (

"github.com/ovh/cds/engine/api/authentication"
"github.com/ovh/cds/engine/api/observability"
"github.com/ovh/cds/engine/api/services"
"github.com/ovh/cds/engine/api/user"
"github.com/ovh/cds/engine/api/worker"
"github.com/ovh/cds/engine/service"
"github.com/ovh/cds/sdk"
"github.com/ovh/cds/sdk/log"
Expand Down Expand Up @@ -76,9 +78,25 @@ func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req *
}
// If the driver was disabled for the consumer that was found, ignore it
if _, ok := api.AuthenticationDrivers[c.Type]; ok {
// Add contacts for consumer's user
if err := user.LoadOptions.WithContacts(ctx, api.mustDB(), c.AuthentifiedUser); err != nil {
return ctx, err
}

// Add service for consumer if exists
s, err := services.LoadByConsumerID(ctx, api.mustDB(), c.ID)
if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
return ctx, err
}
c.Service = s

// Add worker for consumer if exists
w, err := worker.LoadByConsumerID(ctx, api.mustDB(), c.ID)
if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) {
return ctx, err
}
c.Worker = w

consumer = c
}
}
Expand Down
14 changes: 10 additions & 4 deletions engine/api/router_middleware_auth_permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import (
"strconv"

"github.com/ovh/cds/engine/api/authentication"
"github.com/ovh/cds/engine/api/project"
"github.com/ovh/cds/engine/api/cache"
"github.com/ovh/cds/engine/api/observability"
"github.com/ovh/cds/engine/api/project"
"github.com/ovh/cds/engine/api/worker"
"github.com/ovh/cds/engine/api/workflow"

"github.com/ovh/cds/engine/api/action"
Expand Down Expand Up @@ -69,7 +70,12 @@ func (api *API) checkJobIDPermissions(ctx context.Context, jobID string, perm in

// If the expected permission if >= RX and the consumer is a worker
// We check that the worker has took this job
if wk, isWorker := api.isWorker(ctx); isWorker && perm >= sdk.PermissionReadExecute {
if isWorker := isWorker(ctx); isWorker && perm >= sdk.PermissionReadExecute {
wk, err := worker.LoadByID(ctx, api.mustDB(), getAPIConsumer(ctx).Worker.ID)
if err != nil {
return err
}

var ok bool
k := cache.Key("api:workers", getAPIConsumer(ctx).ID, "perm", jobID)
if has, _ := api.Cache.Get(k, &ok); ok && has {
Expand Down Expand Up @@ -98,13 +104,13 @@ func (api *API) checkProjectPermissions(ctx context.Context, projectKey string,
ctx, end := observability.Span(ctx, "api.checkProjectPermissions")
defer end()

if _, err := project.Load(api.mustDB(), api.Cache, projectKey); err != nil {
if _, err := project.Load(api.mustDB(), api.Cache, projectKey); err != nil {
return err
}

perms, err := permission.LoadProjectMaxLevelPermission(ctx, api.mustDB(), []string{projectKey}, getAPIConsumer(ctx).GetGroupIDs())
if err != nil {
return sdk.WrapError(err, "cannot get max project permissions for %s", projectKey)
return sdk.WrapError(err, "cannot get max project permissions for %s", projectKey)
}

callerPermission := perms.Level(projectKey)
Expand Down
34 changes: 19 additions & 15 deletions engine/api/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,38 +103,42 @@ func (api *API) postServiceRegisterHandler() service.Handler {

func (api *API) postServiceHearbeatHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
if ok := isService(ctx); !ok {
return sdk.WithStack(sdk.ErrForbidden)
}

s, err := services.LoadByID(ctx, api.mustDB(), getAPIConsumer(ctx).Service.ID)
if err != nil {
return err
}

var mon sdk.MonitoringStatus
if err := service.UnmarshalBody(r, &mon); err != nil {
return sdk.WithStack(err)
return err
}

// Update status to warn if service version != api version
for i := range mon.Lines {
s := &mon.Lines[i]
if s.Component == "Version" {
if sdk.VERSION != s.Value {
s.Status = sdk.MonitoringStatusWarn
if mon.Lines[i].Component == "Version" {
if sdk.VERSION != mon.Lines[i].Value {
mon.Lines[i].Status = sdk.MonitoringStatusWarn
} else {
s.Status = sdk.MonitoringStatusOK
mon.Lines[i].Status = sdk.MonitoringStatusOK
}
break
}
}

tx, err := api.mustDB().Begin()
if err != nil {
return sdk.WrapError(err, "Cannot start transaction")
return sdk.WithStack(err)
}
defer tx.Rollback() // nolint

srv, ok := api.isService(ctx)
if !ok {
return sdk.ErrForbidden
}
s.LastHeartbeat = time.Now()
s.MonitoringStatus = mon

srv.LastHeartbeat = time.Now()
srv.MonitoringStatus = mon

if err := services.Update(ctx, tx, srv); err != nil {
if err := services.Update(ctx, tx, s); err != nil {
return err
}

Expand Down
1 change: 0 additions & 1 deletion engine/api/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,4 @@ func TestServicesHandlers(t *testing.T) {
require.Equal(t, 204, rec.Code)

require.NoError(t, services.Delete(api.mustDB(), &srv))

}
Loading

0 comments on commit c4f892c

Please sign in to comment.