feat(queries): user grants (#2838)

* refactor(domain): add user type

* fix(projections): start with login names

* fix(login_policy): correct handling of user domain claimed event

* fix(projections): add members

* refactor: simplify member projections

* add migration for members

* add metadata to member projections

* refactor: login name projection

* fix: set correct suffixes on login name projections

* test(projections): login name reduces

* fix: correct cols in reduce member

* test(projections): org, iam, project members

* member additional cols and conds as opt,
add project grant members

* fix(migration): members

* fix(migration): correct database name

* migration version

* migs

* better naming for member cond and col

* split project and project grant members

* prepare member columns

* feat(queries): membership query

* test(queries): membership prepare

* fix(queries): multiple projections for latest sequence

* fix(api): use query for membership queries in auth and management

* feat: org member queries

* fix(api): use query for iam member calls

* fix(queries): org members

* fix(queries): project members

* fix(queries): project grant members

* fix(query): member queries and user avatar column

* member cols

* fix(queries): membership stmt

* fix user test

* fix user test

* fix(projections): add user grant projection

* fix(user_grant): handle state changes

* add state to migration

* fix(management): use query for user grant requests

* merge eventstore-naming into user-grant-projection

* feat(queries): user grants

* fix(migrations): version

* fix(api): user query for user grants

* fix(query): event mappers for usergrant aggregate

* fix(projection): correct aggregate for user grants

* fix(queries): user grant roles as list contains

* cleanup reducers

* fix avater_key to avatar_key

* tests

* cleanup

* cleanup

* add resourceowner query

* fix: user grant project name search query

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
Silvan
2022-01-14 10:45:50 +01:00
committed by GitHub
parent a63a995269
commit c542cab4f8
29 changed files with 1546 additions and 816 deletions

View File

@@ -44,6 +44,7 @@ const sqlPlaceholder = "?"
type SearchQuery interface {
toQuery(sq.SelectBuilder) sq.SelectBuilder
comp() sq.Sqlizer
}
type NotNullQuery struct {
@@ -60,7 +61,34 @@ func NewNotNullQuery(col Column) (*NotNullQuery, error) {
}
func (q *NotNullQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
return query.Where(sq.NotEq{q.Column.identifier(): nil})
return query.Where(q.comp())
}
func (q *NotNullQuery) comp() sq.Sqlizer {
return sq.NotEq{q.Column.identifier(): nil}
}
type orQuery struct {
queries []SearchQuery
}
func newOrQuery(queries ...SearchQuery) (*orQuery, error) {
if len(queries) == 0 {
return nil, ErrMissingColumn
}
return &orQuery{queries: queries}, nil
}
func (q *orQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
return query.Where(q.comp())
}
func (q *orQuery) comp() sq.Sqlizer {
or := make(sq.Or, len(q.queries))
for i, query := range q.queries {
or[i] = query.comp()
}
return or
}
type TextQuery struct {
@@ -90,32 +118,31 @@ func NewTextQuery(col Column, value string, compare TextComparison) (*TextQuery,
}
func (q *TextQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
where, args := q.comp()
return query.Where(where, args...)
return query.Where(q.comp())
}
func (s *TextQuery) comp() (comparison interface{}, args []interface{}) {
func (s *TextQuery) comp() sq.Sqlizer {
switch s.Compare {
case TextEquals:
return sq.Eq{s.Column.identifier(): s.Text}, nil
return sq.Eq{s.Column.identifier(): s.Text}
case TextEqualsIgnoreCase:
return sq.ILike{s.Column.identifier(): s.Text}, nil
return sq.ILike{s.Column.identifier(): s.Text}
case TextStartsWith:
return sq.Like{s.Column.identifier(): s.Text + "%"}, nil
return sq.Like{s.Column.identifier(): s.Text + "%"}
case TextStartsWithIgnoreCase:
return sq.ILike{s.Column.identifier(): s.Text + "%"}, nil
return sq.ILike{s.Column.identifier(): s.Text + "%"}
case TextEndsWith:
return sq.Like{s.Column.identifier(): "%" + s.Text}, nil
return sq.Like{s.Column.identifier(): "%" + s.Text}
case TextEndsWithIgnoreCase:
return sq.ILike{s.Column.identifier(): "%" + s.Text}, nil
return sq.ILike{s.Column.identifier(): "%" + s.Text}
case TextContains:
return sq.Like{s.Column.identifier(): "%" + s.Text + "%"}, nil
return sq.Like{s.Column.identifier(): "%" + s.Text + "%"}
case TextContainsIgnoreCase:
return sq.ILike{s.Column.identifier(): "%" + s.Text + "%"}, nil
return sq.ILike{s.Column.identifier(): "%" + s.Text + "%"}
case TextListContains:
return s.Column.identifier() + " @> ? ", []interface{}{pq.StringArray{s.Text}}
return &listContains{col: s.Column, args: []interface{}{pq.StringArray{s.Text}}}
}
return nil, nil
return nil
}
type TextComparison int
@@ -187,24 +214,23 @@ func NewNumberQuery(c Column, value interface{}, compare NumberComparison) (*Num
}
func (q *NumberQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
where, args := q.comp()
return query.Where(where, args...)
return query.Where(q.comp())
}
func (s *NumberQuery) comp() (comparison interface{}, args []interface{}) {
func (s *NumberQuery) comp() sq.Sqlizer {
switch s.Compare {
case NumberEquals:
return sq.Eq{s.Column.identifier(): s.Number}, nil
return sq.Eq{s.Column.identifier(): s.Number}
case NumberNotEquals:
return sq.NotEq{s.Column.identifier(): s.Number}, nil
return sq.NotEq{s.Column.identifier(): s.Number}
case NumberLess:
return sq.Lt{s.Column.identifier(): s.Number}, nil
return sq.Lt{s.Column.identifier(): s.Number}
case NumberGreater:
return sq.Gt{s.Column.identifier(): s.Number}, nil
return sq.Gt{s.Column.identifier(): s.Number}
case NumberListContains:
return s.Column.identifier() + " @> ? ", []interface{}{pq.Array(s.Number)}
return &listContains{col: s.Column, args: []interface{}{pq.GenericArray{s.Number}}}
}
return nil, nil
return nil
}
type NumberComparison int
@@ -258,16 +284,15 @@ func NewListQuery(column Column, value []interface{}, compare ListComparison) (*
}
func (q *ListQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
where, args := q.comp()
return query.Where(where, args...)
return query.Where(q.comp())
}
func (s *ListQuery) comp() (interface{}, []interface{}) {
func (s *ListQuery) comp() sq.Sqlizer {
switch s.Compare {
case ListIn:
return sq.Eq{s.Column.identifier(): s.List}, nil
return sq.Eq{s.Column.identifier(): s.List}
}
return nil, nil
return nil
}
type ListComparison int
@@ -300,12 +325,11 @@ func NewBoolQuery(c Column, value bool) (*BoolQuery, error) {
}
func (q *BoolQuery) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
where, args := q.comp()
return query.Where(where, args...)
return query.Where(q.comp())
}
func (s *BoolQuery) comp() (comparison interface{}, args []interface{}) {
return sq.Eq{s.Column.identifier(): s.Value}, nil
func (s *BoolQuery) comp() sq.Sqlizer {
return sq.Eq{s.Column.identifier(): s.Value}
}
var (
@@ -367,3 +391,12 @@ func (c Column) isZero() bool {
func join(join, from Column) string {
return join.table.identifier() + " ON " + from.identifier() + " = " + join.identifier()
}
type listContains struct {
col Column
args []interface{}
}
func (q *listContains) ToSql() (string, []interface{}, error) {
return q.col.identifier() + " @> ? ", q.args, nil
}