• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

goto / guardian / 9344046161

03 Jun 2024 03:59AM UTC coverage: 74.915% (-0.3%) from 75.222%
9344046161

Pull #125

github

rahmatrhd
chore: add additional checking for isExpired
Pull Request #125: feat(grant): add restore grant API

34 of 108 new or added lines in 4 files covered. (31.48%)

73 existing lines in 3 files now uncovered.

9664 of 12900 relevant lines covered (74.91%)

4.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/domain/grant.go
1
package domain
2

3
import (
4
        "errors"
5
        "fmt"
6
        "sort"
7
        "strings"
8
        "time"
9
)
10

11
type GrantStatus string
12
type GrantSource string
13

14
const (
15
        GrantStatusActive   GrantStatus = "active"
16
        GrantStatusInactive GrantStatus = "inactive"
17

18
        GrantSourceAppeal GrantSource = "appeal"
19
        GrantSourceImport GrantSource = "import"
20

21
        GrantExpirationReasonDormant  = "grant/access hasn't been used for a while"
22
        GrantExpirationReasonRestored = "grant restored with new duration"
23
)
24

25
var ErrDuplicateActiveGrant = errors.New("grant already exists")
26

27
type Grant struct {
28
        ID                      string      `json:"id" yaml:"id"`
29
        Status                  GrantStatus `json:"status" yaml:"status"`
30
        StatusInProvider        GrantStatus `json:"status_in_provider" yaml:"status_in_provider"`
31
        AccountID               string      `json:"account_id" yaml:"account_id"`
32
        AccountType             string      `json:"account_type" yaml:"account_type"`
33
        ResourceID              string      `json:"resource_id" yaml:"resource_id"`
34
        Role                    string      `json:"role" yaml:"role"`
35
        Permissions             []string    `json:"permissions" yaml:"permissions"`
36
        IsPermanent             bool        `json:"is_permanent" yaml:"is_permanent"`
37
        ExpirationDate          *time.Time  `json:"expiration_date" yaml:"expiration_date"`
38
        RequestedExpirationDate *time.Time  `json:"requested_expiration_date,omitempty" yaml:"requested_expiration_date,omitempty"`
39
        ExpirationDateReason    string      `json:"expiration_date_reason,omitempty" yaml:"expiration_date_reason,omitempty"`
40
        AppealID                string      `json:"appeal_id" yaml:"appeal_id"`
41
        Source                  GrantSource `json:"source" yaml:"source"`
42
        RevokedBy               string      `json:"revoked_by,omitempty" yaml:"revoked_by,omitempty"`
43
        RevokedAt               *time.Time  `json:"revoked_at,omitempty" yaml:"revoked_at,omitempty"`
44
        RevokeReason            string      `json:"revoke_reason,omitempty" yaml:"revoke_reason,omitempty"`
45
        RestoredBy              string      `json:"restored_by,omitempty" yaml:"restored_by,omitempty"`
46
        RestoredAt              *time.Time  `json:"restored_at,omitempty" yaml:"restored_at,omitempty"`
47
        RestoreReason           string      `json:"restore_reason,omitempty" yaml:"restore_reason,omitempty"`
48
        CreatedBy               string      `json:"created_by" yaml:"created_by"` // Deprecated: use Owner instead
49
        Owner                   string      `json:"owner" yaml:"owner"`
50
        CreatedAt               time.Time   `json:"created_at" yaml:"created_at"`
51
        UpdatedAt               time.Time   `json:"updated_at" yaml:"updated_at"`
52

53
        Resource   *Resource   `json:"resource,omitempty" yaml:"resource,omitempty"`
54
        Appeal     *Appeal     `json:"appeal,omitempty" yaml:"appeal,omitempty"`
55
        Activities []*Activity `json:"activities,omitempty" yaml:"activities,omitempty"`
56
}
57

UNCOV
58
func (g Grant) PermissionsKey() string {
×
UNCOV
59
        permissions := make([]string, len(g.Permissions))
×
UNCOV
60
        copy(permissions, g.Permissions)
×
61
        sort.Strings(permissions)
×
62
        return strings.Join(permissions, ";")
×
63
}
×
64

65
func (g Grant) IsEligibleForExtension(extensionDurationRule time.Duration) bool {
×
66
        if g.ExpirationDate != nil && !g.ExpirationDate.IsZero() {
×
UNCOV
67
                return time.Until(*g.ExpirationDate) <= extensionDurationRule
×
68
        }
×
69
        return true
×
70
}
71

72
func (g *Grant) Revoke(actor, reason string) error {
×
UNCOV
73
        if g == nil {
×
UNCOV
74
                return errors.New("grant is nil")
×
75
        }
×
76
        if actor == "" {
×
77
                return errors.New("actor shouldn't be empty")
×
78
        }
×
79

80
        g.Status = GrantStatusInactive
×
81
        g.RevokedBy = actor
×
UNCOV
82
        g.RevokeReason = reason
×
83
        now := time.Now()
×
84
        g.RevokedAt = &now
×
85
        return nil
×
86
}
87

NEW
88
func (g *Grant) Restore(actor, reason string) error {
×
NEW
UNCOV
89
        if actor == "" {
×
NEW
UNCOV
90
                return errors.New("actor is required")
×
NEW
91
        }
×
NEW
92
        if reason == "" {
×
NEW
93
                return errors.New("reason is required")
×
NEW
94
        }
×
95

NEW
96
        if g.isExpired() {
×
NEW
97
                return fmt.Errorf("grant is already expired at: %s", g.ExpirationDate)
×
NEW
98
        }
×
99

NEW
100
        g.Status = GrantStatusActive
×
NEW
101
        g.StatusInProvider = GrantStatusActive
×
NEW
102

×
NEW
103
        now := time.Now()
×
NEW
104
        g.RestoredAt = &now
×
NEW
105
        g.RestoredBy = actor
×
NEW
106
        g.RestoreReason = reason
×
NEW
107
        g.UpdatedAt = now
×
NEW
108

×
NEW
109
        return nil
×
110
}
111

NEW
112
func (g *Grant) isExpired() bool {
×
NEW
113
        return !g.IsPermanent && g.ExpirationDate != nil && time.Now().After(*g.ExpirationDate)
×
NEW
114
}
×
115

116
func (g *Grant) GetPermissions() []string {
×
117
        var permissions []string
×
118
        for _, p := range g.Permissions {
×
119
                permissions = append(permissions, p)
×
120
        }
×
121
        return permissions
×
122
}
123

124
type ListGrantsFilter struct {
125
        Statuses                  []string
126
        AccountIDs                []string
127
        AccountTypes              []string
128
        ResourceIDs               []string
129
        Roles                     []string
130
        Permissions               []string
131
        ProviderTypes             []string
132
        ProviderURNs              []string
133
        ResourceTypes             []string
134
        ResourceURNs              []string
135
        CreatedBy                 string
136
        Owner                     string
137
        OrderBy                   []string
138
        ExpirationDateLessThan    time.Time
139
        ExpirationDateGreaterThan time.Time
140
        IsPermanent               *bool
141
        CreatedAtLte              time.Time
142
        Size                      int    `mapstructure:"size" validate:"omitempty"`
143
        Offset                    int    `mapstructure:"offset" validate:"omitempty"`
144
        Q                         string `mapstructure:"q" validate:"omitempty"`
145
}
146

147
type RevokeGrantsFilter struct {
148
        AccountIDs    []string `validate:"omitempty,required"`
149
        ProviderTypes []string `validate:"omitempty,min=1"`
150
        ProviderURNs  []string `validate:"omitempty,min=1"`
151
        ResourceTypes []string `validate:"omitempty,min=1"`
152
        ResourceURNs  []string `validate:"omitempty,min=1"`
153
}
154

155
type AccessEntry struct {
156
        AccountID   string
157
        AccountType string
158
        Permission  string
159
}
160

UNCOV
161
func (ae AccessEntry) ToGrant(resource Resource) Grant {
×
UNCOV
162
        g := Grant{
×
UNCOV
163
                ResourceID:       resource.ID,
×
164
                Status:           GrantStatusActive,
×
165
                StatusInProvider: GrantStatusActive,
×
166
                AccountID:        ae.AccountID,
×
167
                AccountType:      ae.AccountType,
×
168
                Role:             ae.Permission,
×
169
                Permissions:      []string{ae.Permission},
×
170
                Source:           GrantSourceImport,
×
171
                IsPermanent:      true,
×
172
        }
×
173
        if ae.AccountType == "user" {
×
174
                g.Owner = ae.AccountID
×
175
        }
×
176
        return g
×
177
}
178

179
// MapResourceAccess is list of UserAccess grouped by resource urn
180
type MapResourceAccess map[string][]AccessEntry
181

182
type DormancyCheckCriteria struct {
183
        ProviderID     string
184
        Period         time.Duration
185
        RetainDuration time.Duration
186
        DryRun         bool
187
}
188

UNCOV
189
func (c DormancyCheckCriteria) Validate() error {
×
UNCOV
190
        if c.ProviderID == "" {
×
UNCOV
191
                return errors.New("provider id is required")
×
192
        }
×
193
        if c.Period == 0 {
×
194
                return errors.New("period is required")
×
195
        } else if c.Period < 0 {
×
196
                return errors.New("period must be positive")
×
197
        }
×
198
        if c.RetainDuration == 0 {
×
199
                return errors.New("retain duration is required")
×
200
        } else if c.RetainDuration < 0 {
×
201
                return errors.New("retain duration must be positive")
×
202
        }
×
203
        return nil
×
204
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc