This repository has been archived by the owner on Mar 11, 2021. It is now read-only.
/
default_role_mapping.go
200 lines (169 loc) · 8.03 KB
/
default_role_mapping.go
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
package repository
import (
"context"
"fmt"
"time"
"github.com/fabric8-services/fabric8-auth/application/repository/base"
resourcetype "github.com/fabric8-services/fabric8-auth/authorization/resourcetype/repository"
"github.com/fabric8-services/fabric8-auth/errors"
"github.com/fabric8-services/fabric8-auth/gormsupport"
"github.com/fabric8-services/fabric8-auth/log"
"github.com/goadesign/goa"
"github.com/jinzhu/gorm"
errs "github.com/pkg/errors"
"github.com/satori/go.uuid"
)
// DefaultRoleMapping is used to define a rule for creating role mappings when registering new resources. A role
// mapping allows an identity with a certain role for the resource to automatically inherit the privileges of another
// role for certain types of descendent resources. For example, a default role mapping rule that maps from the
// organization:admin role (FromRole) to the space:admin role (ToRole) for an organization (ResourceType) resource
// means that any identities that are assigned the admin role for the newly created organization, also inherit the
// admin role for any space resources that are under that organization.
type DefaultRoleMapping struct {
gormsupport.Lifecycle
// This is the primary key value
DefaultRoleMappingID uuid.UUID `sql:"type:uuid default uuid_generate_v4()" gorm:"primary_key;column:default_role_mapping_id"`
// The resource type that this role mapping applies to
ResourceType resourcetype.ResourceType `gorm:"ForeignKey:ResourceTypeID;AssociationForeignKey:ResourceTypeID"`
// The foreign key value for ResourceType
ResourceTypeID uuid.UUID
// The role that is being mapped from
FromRole Role `gorm:"ForeignKey:RoleID;AssociationForeignKey:FromRoleID"`
// The foreign key value for FromRole
FromRoleID uuid.UUID
// The role that is being mapped to
ToRole Role `gorm:"ForeignKey:RoleID;AssociationForeignKey:ToRoleID"`
// The foreign key value for ToRole
ToRoleID uuid.UUID
}
func (m DefaultRoleMapping) TableName() string {
return "default_role_mapping"
}
// GetLastModified returns the last modification time
func (m DefaultRoleMapping) GetLastModified() time.Time {
return m.UpdatedAt
}
// GormDefaultRoleRepository is the implementation of the storage interface for Role.
type GormDefaultRoleMappingRepository struct {
db *gorm.DB
}
// NewDefaultRoleMappingRepository creates a new storage type.
func NewDefaultRoleMappingRepository(db *gorm.DB) DefaultRoleMappingRepository {
return &GormDefaultRoleMappingRepository{db: db}
}
// DefaultRoleMappingRepository represents the storage interface.
type DefaultRoleMappingRepository interface {
CheckExists(ctx context.Context, ID uuid.UUID) error
Load(ctx context.Context, ID uuid.UUID) (*DefaultRoleMapping, error)
Create(ctx context.Context, u *DefaultRoleMapping) error
Save(ctx context.Context, u *DefaultRoleMapping) error
List(ctx context.Context) ([]DefaultRoleMapping, error)
Delete(ctx context.Context, ID uuid.UUID) error
FindForResourceType(ctx context.Context, resourceTypeID uuid.UUID) ([]DefaultRoleMapping, error)
FindForResourceTypeAndRoles(ctx context.Context, resourceTypeID, fromRoleId, toRoleId uuid.UUID) (*DefaultRoleMapping, error)
}
// TableName overrides the table name settings in Gorm to force a specific table name
// in the database.
func (m *GormDefaultRoleMappingRepository) TableName() string {
return "default_role_mapping"
}
// CheckExists returns nil if the given ID exists otherwise returns an error
func (m *GormDefaultRoleMappingRepository) CheckExists(ctx context.Context, id uuid.UUID) error {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "exists"}, time.Now())
return base.CheckExistsWithCustomIDColumn(ctx, m.db, m.TableName(), "default_role_mapping_id", id.String())
}
// CRUD Functions
// Load returns a single RoleMapping as a Database Model
func (m *GormDefaultRoleMappingRepository) Load(ctx context.Context, id uuid.UUID) (*DefaultRoleMapping, error) {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "load"}, time.Now())
var native DefaultRoleMapping
err := m.db.Table(m.TableName()).
Preload("ResourceType").
Preload("FromRole").
Preload("ToRole").
Where("default_role_mapping_id = ?", id).Find(&native).Error
if err == gorm.ErrRecordNotFound {
return nil, errors.NewNotFoundError("default_role_mapping", id.String())
}
return &native, errs.WithStack(err)
}
// Create creates a new record.
func (m *GormDefaultRoleMappingRepository) Create(ctx context.Context, u *DefaultRoleMapping) error {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "create"}, time.Now())
if u.DefaultRoleMappingID == uuid.Nil {
u.DefaultRoleMappingID = uuid.NewV4()
}
err := m.db.Create(u).Error
if err != nil {
log.Error(ctx, map[string]interface{}{
"default_role_mapping_id": u.DefaultRoleMappingID,
"err": err,
}, "unable to create the default role mapping")
return errs.WithStack(err)
}
log.Debug(ctx, map[string]interface{}{
"default_role_mapping_id": u.DefaultRoleMappingID,
}, "Default role mapping created!")
return nil
}
// Save modifies a single record
func (m *GormDefaultRoleMappingRepository) Save(ctx context.Context, model *DefaultRoleMapping) error {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "save"}, time.Now())
err := m.db.Save(model).Error
if err == nil {
log.Debug(ctx, map[string]interface{}{
"default_role_mapping_id": model.DefaultRoleMappingID,
}, "default role mapping saved")
}
return errs.WithStack(err)
}
// List returns all default role mappings
func (m *GormDefaultRoleMappingRepository) List(ctx context.Context) ([]DefaultRoleMapping, error) {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "list"}, time.Now())
var rows []DefaultRoleMapping
err := m.db.Model(&DefaultRoleMapping{}).Find(&rows).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, errs.WithStack(err)
}
return rows, nil
}
// Delete removes a single record.
func (m *GormDefaultRoleMappingRepository) Delete(ctx context.Context, id uuid.UUID) error {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "delete"}, time.Now())
obj := DefaultRoleMapping{DefaultRoleMappingID: id}
result := m.db.Delete(&obj)
if result.Error != nil {
log.Error(ctx, map[string]interface{}{
"default_role_mapping_id": id,
"err": result.Error,
}, "unable to delete the default role mapping")
return errs.WithStack(result.Error)
}
if result.RowsAffected == 0 {
return errors.NewNotFoundError("default_role_mapping", id.String())
}
log.Debug(ctx, map[string]interface{}{
"default_role_mapping_id": id,
}, "Default role mapping deleted!")
return nil
}
func (m *GormDefaultRoleMappingRepository) FindForResourceType(ctx context.Context, resourceTypeID uuid.UUID) ([]DefaultRoleMapping, error) {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "FindForResourceType"}, time.Now())
var rows []DefaultRoleMapping
err := m.db.Model(&DefaultRoleMapping{}).Where("resource_type_id = ?", resourceTypeID).Find(&rows).Error
if err != nil && err != gorm.ErrRecordNotFound { // TODO: should we wrap the gorm.ErrRecordNotFound into an errors.NotFoundError ?
return nil, errs.WithStack(err)
}
return rows, nil
}
func (m *GormDefaultRoleMappingRepository) FindForResourceTypeAndRoles(ctx context.Context, resourceTypeID, fromRoleId, toRoleId uuid.UUID) (*DefaultRoleMapping, error) {
defer goa.MeasureSince([]string{"goa", "db", "default_role_mapping", "FindForResourceTypeAndRoles"}, time.Now())
var result DefaultRoleMapping
err := m.db.Model(&DefaultRoleMapping{}).Where("resource_type_id = ? AND from_role_id = ? AND to_role_id = ? ", resourceTypeID, fromRoleId, toRoleId).Find(&result).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, errors.NewInternalError(err)
} else if err == gorm.ErrRecordNotFound {
return nil, errors.NewNotFoundErrorFromString(fmt.Sprintf("unable to find default mapping role for resource of type of ID '%v' and from role with ID '%v' to role with ID '%v'", resourceTypeID, fromRoleId, toRoleId))
}
return &result, nil
}