/usr/share/gocode/src/github.com/influxdata/influxdb/services/meta/query_authorizer.go is in golang-github-influxdb-influxdb-dev 1.1.1+dfsg1-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | package meta
import (
"fmt"
"github.com/influxdata/influxdb/influxql"
)
type QueryAuthorizer struct {
Client *Client
}
func NewQueryAuthorizer(c *Client) *QueryAuthorizer {
return &QueryAuthorizer{
Client: c,
}
}
// AuthorizeQuery authorizes u to execute q on database.
// 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 *UserInfo, query *influxql.Query, database string) 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 {
// First statement in the query must create a user with admin privilege.
cu, ok := query.Statements[0].(*influxql.CreateUserStatement)
if ok && cu.Admin == true {
return nil
}
}
return &ErrAuthorize{
Query: query,
Database: database,
Message: "create admin user first or disable authentication",
}
}
if u == nil {
return &ErrAuthorize{
Query: query,
Database: database,
Message: "no user provided",
}
}
// Admin privilege allows the user to execute all statements.
if u.Admin {
return nil
}
// Check each statement in the query.
for _, stmt := range query.Statements {
// Get the privileges required to execute the statement.
privs, err := stmt.RequiredPrivileges()
if err != nil {
return err
}
// Make sure the user has the privileges required to execute
// each statement.
for _, p := range privs {
if p.Admin {
// Admin privilege already checked so statement requiring admin
// privilege cannot be run.
return &ErrAuthorize{
Query: query,
User: u.Name,
Database: database,
Message: fmt.Sprintf("statement '%s', requires admin privilege", stmt),
}
}
// Use the db name specified by the statement or the db
// name passed by the caller if one wasn't specified by
// the statement.
db := p.Name
if db == "" {
db = database
}
if !u.Authorize(p.Privilege, db) {
return &ErrAuthorize{
Query: query,
User: u.Name,
Database: database,
Message: fmt.Sprintf("statement '%s', requires %s on %s", stmt, p.Privilege.String(), db),
}
}
}
}
return nil
}
// ErrAuthorize represents an authorization error.
type ErrAuthorize struct {
Query *influxql.Query
User string
Database string
Message string
}
// Error returns the text of the error.
func (e ErrAuthorize) Error() string {
if e.User == "" {
return fmt.Sprint(e.Message)
}
return fmt.Sprintf("%s not authorized to execute %s", e.User, e.Message)
}
|