Merge branch '20667-maxsuper-atquota'
[arvados.git] / lib / controller / localdb / group.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 package localdb
6
7 import (
8         "context"
9         "fmt"
10         "strings"
11
12         "git.arvados.org/arvados.git/sdk/go/arvados"
13 )
14
15 // GroupCreate defers to railsProxy for everything except vocabulary
16 // checking.
17 func (conn *Conn) GroupCreate(ctx context.Context, opts arvados.CreateOptions) (arvados.Group, error) {
18         conn.logActivity(ctx)
19         err := conn.checkProperties(ctx, opts.Attrs["properties"])
20         if err != nil {
21                 return arvados.Group{}, err
22         }
23         resp, err := conn.railsProxy.GroupCreate(ctx, opts)
24         if err != nil {
25                 return resp, err
26         }
27         return resp, nil
28 }
29
30 func (conn *Conn) GroupGet(ctx context.Context, opts arvados.GetOptions) (arvados.Group, error) {
31         conn.logActivity(ctx)
32         return conn.railsProxy.GroupGet(ctx, opts)
33 }
34
35 // GroupUpdate defers to railsProxy for everything except vocabulary
36 // checking.
37 func (conn *Conn) GroupUpdate(ctx context.Context, opts arvados.UpdateOptions) (arvados.Group, error) {
38         conn.logActivity(ctx)
39         err := conn.checkProperties(ctx, opts.Attrs["properties"])
40         if err != nil {
41                 return arvados.Group{}, err
42         }
43         resp, err := conn.railsProxy.GroupUpdate(ctx, opts)
44         if err != nil {
45                 return resp, err
46         }
47         return resp, nil
48 }
49
50 func (conn *Conn) GroupList(ctx context.Context, opts arvados.ListOptions) (arvados.GroupList, error) {
51         conn.logActivity(ctx)
52         return conn.railsProxy.GroupList(ctx, opts)
53 }
54
55 func (conn *Conn) GroupDelete(ctx context.Context, opts arvados.DeleteOptions) (arvados.Group, error) {
56         conn.logActivity(ctx)
57         return conn.railsProxy.GroupDelete(ctx, opts)
58 }
59
60 func (conn *Conn) GroupContents(ctx context.Context, options arvados.GroupContentsOptions) (arvados.ObjectList, error) {
61         conn.logActivity(ctx)
62
63         // The requested UUID can be a user (virtual home project), which we just pass on to
64         // the API server.
65         if strings.Index(options.UUID, "-j7d0g-") != 5 {
66                 return conn.railsProxy.GroupContents(ctx, options)
67         }
68
69         var resp arvados.ObjectList
70
71         // Get the group object
72         respGroup, err := conn.GroupGet(ctx, arvados.GetOptions{UUID: options.UUID})
73         if err != nil {
74                 return resp, err
75         }
76
77         // If the group has groupClass 'filter', apply the filters before getting the contents.
78         if respGroup.GroupClass == "filter" {
79                 if filters, ok := respGroup.Properties["filters"].([]interface{}); ok {
80                         for _, f := range filters {
81                                 // f is supposed to be a []string
82                                 tmp, ok2 := f.([]interface{})
83                                 if !ok2 || len(tmp) < 3 {
84                                         return resp, fmt.Errorf("filter unparsable: %T, %+v, original field: %T, %+v\n", tmp, tmp, f, f)
85                                 }
86                                 var filter arvados.Filter
87                                 if attr, ok2 := tmp[0].(string); ok2 {
88                                         filter.Attr = attr
89                                 } else {
90                                         return resp, fmt.Errorf("filter unparsable: attribute must be string: %T, %+v, filter: %T, %+v\n", tmp[0], tmp[0], f, f)
91                                 }
92                                 if operator, ok2 := tmp[1].(string); ok2 {
93                                         filter.Operator = operator
94                                 } else {
95                                         return resp, fmt.Errorf("filter unparsable: operator must be string: %T, %+v, filter: %T, %+v\n", tmp[1], tmp[1], f, f)
96                                 }
97                                 filter.Operand = tmp[2]
98                                 options.Filters = append(options.Filters, filter)
99                         }
100                 } else {
101                         return resp, fmt.Errorf("filter unparsable: not an array\n")
102                 }
103                 // Use the generic /groups/contents endpoint for filter groups
104                 options.UUID = ""
105         }
106
107         return conn.railsProxy.GroupContents(ctx, options)
108 }