Fix authentication when subqueries are present

The code that checked if a query was authorized did not account for
sources that were subqueries. Now, the check for the required privileges
will descend into the subquery and add the subqueries required
privileges to the list of required privileges for the entire query.
pull/7952/head
Jonathan A. Sternberg 2017-02-06 09:40:52 -06:00
parent d5ac69be6f
commit caaad60dcf
3 changed files with 48 additions and 8 deletions

View File

@ -8,6 +8,7 @@
- [#7929](https://github.com/influxdata/influxdb/issues/7929): Fix series tag iteration segfault. (#7922)
- [#7906](https://github.com/influxdata/influxdb/issues/7906): Anchors not working as expected with case-insensitive regex
- [#7895](https://github.com/influxdata/influxdb/issues/7895): Fix incorrect math when aggregates that emit different times are used.
- [#7946](https://github.com/influxdata/influxdb/issues/7946): Fix authentication when subqueries are present.
## v1.2.0 [2017-01-24]

View File

@ -1630,15 +1630,21 @@ func (s *SelectStatement) String() string {
func (s *SelectStatement) RequiredPrivileges() (ExecutionPrivileges, error) {
ep := ExecutionPrivileges{}
for _, source := range s.Sources {
measurement, ok := source.(*Measurement)
if !ok {
return nil, fmt.Errorf("invalid measurement: %s", source)
switch source := source.(type) {
case *Measurement:
ep = append(ep, ExecutionPrivilege{
Name: source.Database,
Privilege: ReadPrivilege,
})
case *SubQuery:
privs, err := source.Statement.RequiredPrivileges()
if err != nil {
return nil, err
}
ep = append(ep, privs...)
default:
return nil, fmt.Errorf("invalid source: %s", source)
}
ep = append(ep, ExecutionPrivilege{
Name: measurement.Database,
Privilege: ReadPrivilege,
})
}
if s.Target != nil {

View File

@ -1428,6 +1428,39 @@ func TestSelect_Privileges(t *testing.T) {
}
}
func TestSelect_SubqueryPrivileges(t *testing.T) {
stmt := &influxql.SelectStatement{
Target: &influxql.Target{
Measurement: &influxql.Measurement{Database: "db2"},
},
Sources: []influxql.Source{
&influxql.Measurement{Database: "db0"},
&influxql.SubQuery{
Statement: &influxql.SelectStatement{
Sources: []influxql.Source{
&influxql.Measurement{Database: "db1"},
},
},
},
},
}
exp := influxql.ExecutionPrivileges{
influxql.ExecutionPrivilege{Name: "db0", Privilege: influxql.ReadPrivilege},
influxql.ExecutionPrivilege{Name: "db1", Privilege: influxql.ReadPrivilege},
influxql.ExecutionPrivilege{Name: "db2", Privilege: influxql.WritePrivilege},
}
got, err := stmt.RequiredPrivileges()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(exp, got) {
t.Errorf("exp: %v, got: %v", exp, got)
}
}
func TestSources_Names(t *testing.T) {
sources := influxql.Sources([]influxql.Source{
&influxql.Measurement{