Skip to content

Commit

Permalink
fix: FGA enablement (influxdata#21512)
Browse files Browse the repository at this point in the history
  • Loading branch information
lesam authored May 19, 2021
1 parent 33f0bb3 commit 482a27b
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ v1.9.0 [unreleased]
- [#21348](https://github.com/influxdata/influxdb/pull/21348): fix(storage): cursor requests are [start, stop] instead of [start, stop)
- [#21359](https://github.com/influxdata/influxdb/pull/21359): fix: disable MergeFiltersRule until it is more stable
- [#21489](https://github.com/influxdata/influxdb/pull/21489): chore(ae): add more logging
- [#21512](https://github.com/influxdata/influxdb/pull/21512): fix: FGA enablement


v1.8.6 [unreleased]
Expand Down
5 changes: 3 additions & 2 deletions internal/authorizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package internal

import (
"github.com/influxdata/influxdb/models"
"github.com/influxdata/influxdb/query"
"github.com/influxdata/influxql"
)

Expand All @@ -21,8 +22,8 @@ func (a *AuthorizerMock) AuthorizeDatabase(p influxql.Privilege, name string) bo

// AuthorizeQuery determins if the query can be executed against the provided
// database.
func (a *AuthorizerMock) AuthorizeQuery(database string, query *influxql.Query) error {
return a.AuthorizeQueryFn(database, query)
func (a *AuthorizerMock) AuthorizeQuery(database string, q *influxql.Query) (query.FineAuthorizer, error) {
return a, a.AuthorizeQueryFn(database, q)
}

// AuthorizeSeriesRead determines if the series comprising measurement and tags
Expand Down
21 changes: 13 additions & 8 deletions services/httpd/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ type Route struct {
}

type QueryAuthorizer interface {
AuthorizeQuery(u meta.User, query *influxql.Query, database string) error
AuthorizeQuery(u meta.User, query *influxql.Query, database string) (query.FineAuthorizer, error)
AuthorizeDatabase(u meta.User, priv influxql.Privilege, database string) error
}

Expand Down Expand Up @@ -572,17 +572,23 @@ func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user meta.U
}

// Check authorization.
var fineAuthorizer query.FineAuthorizer
if h.Config.AuthEnabled {
if err := h.QueryAuthorizer.AuthorizeQuery(user, q, db); err != nil {
if err, ok := err.(meta.ErrAuthorize); ok {
var err error
if fineAuthorizer, err = h.QueryAuthorizer.AuthorizeQuery(user, q, db); err != nil {
if authErr, ok := err.(meta.ErrAuthorize); ok {
h.Logger.Info("Unauthorized request",
zap.String("user", err.User),
zap.Stringer("query", err.Query),
logger.Database(err.Database))
zap.String("user", authErr.User),
zap.Stringer("query", authErr.Query),
logger.Database(authErr.Database))
} else {
h.Logger.Info("Error authorizing query", zap.Error(err))
}
h.httpError(rw, "error authorizing query: "+err.Error(), http.StatusForbidden)
return
}
} else {
fineAuthorizer = query.OpenAuthorizer
}

// Parse chunk size. Use default if not provided or unparsable.
Expand All @@ -603,8 +609,7 @@ func (h *Handler) serveQuery(w http.ResponseWriter, r *http.Request, user meta.U
ChunkSize: chunkSize,
ReadOnly: r.Method == "GET",
NodeID: nodeID,
// Authorizer is for fine grained auth, not supported by oss.
Authorizer: query.OpenAuthorizer,
Authorizer: fineAuthorizer,
}

if h.Config.AuthEnabled {
Expand Down
4 changes: 2 additions & 2 deletions services/httpd/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2162,8 +2162,8 @@ type HandlerQueryAuthorizer struct {
AuthorizeQueryFn func(u meta.User, query *influxql.Query, database string) error
}

func (a *HandlerQueryAuthorizer) AuthorizeQuery(u meta.User, query *influxql.Query, database string) error {
return a.AuthorizeQueryFn(u, query, database)
func (a *HandlerQueryAuthorizer) AuthorizeQuery(u meta.User, q *influxql.Query, database string) (query.FineAuthorizer, error) {
return query.OpenAuthorizer, a.AuthorizeQueryFn(u, q, database)
}

func (a *HandlerQueryAuthorizer) AuthorizeDatabase(u meta.User, priv influxql.Privilege, database string) error {
Expand Down
3 changes: 1 addition & 2 deletions services/meta/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package meta

import (
"errors"
"fmt"
"net"
"net/url"
"sort"
Expand All @@ -10,8 +11,6 @@ import (
"time"
"unicode"

"fmt"

"github.com/gogo/protobuf/proto"
"github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/models"
Expand Down
38 changes: 19 additions & 19 deletions services/meta/query_authorizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package meta
import (
"fmt"

"github.com/influxdata/influxdb/query"
"github.com/influxdata/influxql"
)

Expand All @@ -22,27 +23,27 @@ func NewQueryAuthorizer(c *Client) *QueryAuthorizer {
// Database can be "" for queries that do not require a database.
// If no user is provided it will return an error unless the query's first statement is to create
// a root user.
func (a *QueryAuthorizer) AuthorizeQuery(u User, query *influxql.Query, database string) error {
func (a *QueryAuthorizer) AuthorizeQuery(u User, q *influxql.Query, database string) (query.FineAuthorizer, error) {
// Special case if no users exist.
if n := a.Client.UserCount(); n == 0 {
// Ensure there is at least one statement.
if len(query.Statements) > 0 {
if len(q.Statements) > 0 {
// First statement in the query must create a user with admin privilege.
cu, ok := query.Statements[0].(*influxql.CreateUserStatement)
cu, ok := q.Statements[0].(*influxql.CreateUserStatement)
if ok && cu.Admin {
return nil
return query.OpenAuthorizer, nil
}
}
return &ErrAuthorize{
Query: query,
return nil, &ErrAuthorize{
Query: q,
Database: database,
Message: "create admin user first or disable authentication",
}
}

if u == nil {
return &ErrAuthorize{
Query: query,
return nil, &ErrAuthorize{
Query: q,
Database: database,
Message: "no user provided",
}
Expand All @@ -55,15 +56,15 @@ func (a *QueryAuthorizer) AuthorizeQuery(u User, query *influxql.Query, database
case *UserInfo:
// Admin privilege allows the user to execute all statements.
if user.Admin {
return nil
return query.OpenAuthorizer, nil
}

// Check each statement in the query.
for _, stmt := range query.Statements {
for _, stmt := range q.Statements {
// Get the privileges required to execute the statement.
privs, err := stmt.RequiredPrivileges()
if err != nil {
return err
return nil, err
}

// Make sure the user has the privileges required to execute
Expand All @@ -72,8 +73,8 @@ func (a *QueryAuthorizer) AuthorizeQuery(u User, query *influxql.Query, database
if p.Admin {
// Admin privilege already checked so statement requiring admin
// privilege cannot be run.
return &ErrAuthorize{
Query: query,
return nil, &ErrAuthorize{
Query: q,
User: user.Name,
Database: database,
Message: fmt.Sprintf("statement '%s', requires admin privilege", stmt),
Expand All @@ -88,20 +89,20 @@ func (a *QueryAuthorizer) AuthorizeQuery(u User, query *influxql.Query, database
db = database
}
if !user.AuthorizeDatabase(p.Privilege, db) {
return &ErrAuthorize{
Query: query,
return nil, &ErrAuthorize{
Query: q,
User: user.Name,
Database: database,
Message: fmt.Sprintf("statement '%s', requires %s on %s", stmt, p.Privilege.String(), db),
}
}
}
}
return nil
return query.OpenAuthorizer, nil
default:
}
return &ErrAuthorize{
Query: query,
return nil, &ErrAuthorize{
Query: q,
User: u.ID(),
Database: database,
Message: fmt.Sprintf("Invalid OSS user type %T", u),
Expand Down Expand Up @@ -132,7 +133,6 @@ func (a *QueryAuthorizer) AuthorizeDatabase(u User, priv influxql.Privilege, dat
User: u.ID(),
Message: fmt.Sprintf("Internal error - incorrect oss user type %T", u),
}

}

// ErrAuthorize represents an authorization error.
Expand Down

0 comments on commit 482a27b

Please sign in to comment.