ajout app
This commit is contained in:
572
Voltaserve/api/repo/file_repo.go
Normal file
572
Voltaserve/api/repo/file_repo.go
Normal file
@ -0,0 +1,572 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/helper"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type FileInsertOptions struct {
|
||||
Name string
|
||||
WorkspaceID string
|
||||
ParentID *string
|
||||
Type string
|
||||
}
|
||||
|
||||
type FileRepo interface {
|
||||
Insert(opts FileInsertOptions) (model.File, error)
|
||||
Find(id string) (model.File, error)
|
||||
FindChildren(id string) ([]model.File, error)
|
||||
FindPath(id string) ([]model.File, error)
|
||||
FindTree(id string) ([]model.File, error)
|
||||
GetIDsByWorkspace(workspaceID string) ([]string, error)
|
||||
AssignSnapshots(cloneID string, originalID string) error
|
||||
MoveSourceIntoTarget(targetID string, sourceID string) error
|
||||
Save(file model.File) error
|
||||
BulkInsert(values []model.File, chunkSize int) error
|
||||
BulkInsertPermissions(values []*UserPermission, chunkSize int) error
|
||||
Delete(id string) error
|
||||
GetChildrenIDs(id string) ([]string, error)
|
||||
GetItemCount(id string) (int64, error)
|
||||
IsGrandChildOf(id string, ancestorID string) (bool, error)
|
||||
GetSize(id string) (int64, error)
|
||||
GrantUserPermission(id string, userID string, permission string) error
|
||||
RevokeUserPermission(id string, userID string) error
|
||||
GrantGroupPermission(id string, groupID string, permission string) error
|
||||
RevokeGroupPermission(id string, groupID string) error
|
||||
}
|
||||
|
||||
func NewFileRepo() FileRepo {
|
||||
return newFileRepo()
|
||||
}
|
||||
|
||||
func NewFile() model.File {
|
||||
return &fileEntity{}
|
||||
}
|
||||
|
||||
type fileEntity struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
WorkspaceID string `json:"workspaceId" gorm:"column:workspace_id"`
|
||||
Name string `json:"name" gorm:"column:name"`
|
||||
Type string `json:"type" gorm:"column:type"`
|
||||
ParentID *string `json:"parentId,omitempty" gorm:"column:parent_id"`
|
||||
Snapshots []*snapshotEntity `json:"snapshots,omitempty" gorm:"-"`
|
||||
UserPermissions []*userPermissionValue `json:"userPermissions" gorm:"-"`
|
||||
GroupPermissions []*groupPermissionValue `json:"groupPermissions" gorm:"-"`
|
||||
Text *string `json:"text,omitempty" gorm:"-"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime,omitempty" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*fileEntity) TableName() string {
|
||||
return "file"
|
||||
}
|
||||
|
||||
func (f *fileEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
f.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fileEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
f.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetID() string {
|
||||
return f.ID
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetWorkspaceID() string {
|
||||
return f.WorkspaceID
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetName() string {
|
||||
return f.Name
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetType() string {
|
||||
return f.Type
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetParentID() *string {
|
||||
return f.ParentID
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetSnapshots() []model.Snapshot {
|
||||
var res []model.Snapshot
|
||||
for _, s := range f.Snapshots {
|
||||
res = append(res, s)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetUserPermissions() []model.CoreUserPermission {
|
||||
var res []model.CoreUserPermission
|
||||
for _, p := range f.UserPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetGroupPermissions() []model.CoreGroupPermission {
|
||||
var res []model.CoreGroupPermission
|
||||
for _, p := range f.GroupPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetText() *string {
|
||||
return f.Text
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetCreateTime() string {
|
||||
return f.CreateTime
|
||||
}
|
||||
|
||||
func (f *fileEntity) GetUpdateTime() *string {
|
||||
return f.UpdateTime
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetID(id string) {
|
||||
f.ID = id
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetParentID(parentID *string) {
|
||||
f.ParentID = parentID
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetWorkspaceID(workspaceID string) {
|
||||
f.WorkspaceID = workspaceID
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetType(fileType string) {
|
||||
f.Type = fileType
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetName(name string) {
|
||||
f.Name = name
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetText(text *string) {
|
||||
f.Text = text
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetCreateTime(createTime string) {
|
||||
f.CreateTime = createTime
|
||||
}
|
||||
|
||||
func (f *fileEntity) SetUpdateTime(updateTime *string) {
|
||||
f.UpdateTime = updateTime
|
||||
}
|
||||
|
||||
type fileRepo struct {
|
||||
db *gorm.DB
|
||||
snapshotRepo *snapshotRepo
|
||||
permissionRepo *permissionRepo
|
||||
}
|
||||
|
||||
func newFileRepo() *fileRepo {
|
||||
return &fileRepo{
|
||||
db: infra.GetDb(),
|
||||
snapshotRepo: newSnapshotRepo(),
|
||||
permissionRepo: newPermissionRepo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *fileRepo) Insert(opts FileInsertOptions) (model.File, error) {
|
||||
id := helper.NewID()
|
||||
file := fileEntity{
|
||||
ID: id,
|
||||
WorkspaceID: opts.WorkspaceID,
|
||||
Name: opts.Name,
|
||||
Type: opts.Type,
|
||||
ParentID: opts.ParentID,
|
||||
}
|
||||
if db := repo.db.Save(&file); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.populateModelFields([]*fileEntity{res}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) Find(id string) (model.File, error) {
|
||||
file, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.populateModelFields([]*fileEntity{file}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) find(id string) (*fileEntity, error) {
|
||||
var res = fileEntity{}
|
||||
db := repo.db.Raw("SELECT * FROM file WHERE id = ?", id).Scan(&res)
|
||||
if db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewFileNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
if len(res.ID) == 0 {
|
||||
return nil, errorpkg.NewFileNotFoundError(db.Error)
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) FindChildren(id string) ([]model.File, error) {
|
||||
var entities []*fileEntity
|
||||
db := repo.db.Raw("SELECT * FROM file WHERE parent_id = ? ORDER BY create_time ASC", id).Scan(&entities)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
if err := repo.populateModelFields(entities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []model.File
|
||||
for _, f := range entities {
|
||||
res = append(res, f)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) FindPath(id string) ([]model.File, error) {
|
||||
var entities []*fileEntity
|
||||
if db := repo.db.
|
||||
Raw("WITH RECURSIVE rec (id, name, type, parent_id, workspace_id, create_time, update_time) AS "+
|
||||
"(SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM file f WHERE f.id = ? "+
|
||||
"UNION SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM rec, file f WHERE f.id = rec.parent_id) "+
|
||||
"SELECT * FROM rec", id).
|
||||
Scan(&entities); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
if err := repo.populateModelFields(entities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []model.File
|
||||
for _, f := range entities {
|
||||
res = append(res, f)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) FindTree(id string) ([]model.File, error) {
|
||||
var entities []*fileEntity
|
||||
db := repo.db.
|
||||
Raw("WITH RECURSIVE rec (id, name, type, parent_id, workspace_id, create_time, update_time) AS "+
|
||||
"(SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM file f WHERE f.id = ? "+
|
||||
"UNION SELECT f.id, f.name, f.type, f.parent_id, f.workspace_id, f.create_time, f.update_time FROM rec, file f WHERE f.parent_id = rec.id) "+
|
||||
"SELECT rec.* FROM rec ORDER BY create_time ASC", id).
|
||||
Scan(&entities)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
if err := repo.populateModelFields(entities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []model.File
|
||||
for _, f := range entities {
|
||||
res = append(res, f)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) GetIDsByWorkspace(workspaceID string) ([]string, error) {
|
||||
type IDResult struct {
|
||||
Result string
|
||||
}
|
||||
var ids []IDResult
|
||||
db := repo.db.Raw("SELECT id result FROM file WHERE workspace_id = ? ORDER BY create_time ASC", workspaceID).Scan(&ids)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, id := range ids {
|
||||
res = append(res, id.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) AssignSnapshots(cloneID string, originalID string) error {
|
||||
if db := repo.db.Exec("INSERT INTO snapshot_file (snapshot_id, file_id) SELECT s.id, ? "+
|
||||
"FROM snapshot s LEFT JOIN snapshot_file map ON s.id = map.snapshot_id "+
|
||||
"WHERE map.file_id = ? ORDER BY s.version DESC LIMIT 1", cloneID, originalID); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) MoveSourceIntoTarget(targetID string, sourceID string) error {
|
||||
if db := repo.db.Exec("UPDATE file SET parent_id = ? WHERE id = ?", targetID, sourceID); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) Save(file model.File) error {
|
||||
if db := repo.db.Save(file); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) BulkInsert(values []model.File, chunkSize int) error {
|
||||
var entities []*fileEntity
|
||||
for _, f := range values {
|
||||
entities = append(entities, f.(*fileEntity))
|
||||
}
|
||||
if db := repo.db.CreateInBatches(entities, chunkSize); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) BulkInsertPermissions(values []*UserPermission, chunkSize int) error {
|
||||
if db := repo.db.CreateInBatches(values, chunkSize); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) Delete(id string) error {
|
||||
db := repo.db.Exec("DELETE FROM file WHERE id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM userpermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM grouppermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) GetChildrenIDs(id string) ([]string, error) {
|
||||
type Result struct {
|
||||
Result string
|
||||
}
|
||||
var results []Result
|
||||
db := repo.db.Raw("SELECT id result FROM file WHERE parent_id = ? ORDER BY create_time ASC", id).Scan(&results)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, v := range results {
|
||||
res = append(res, v.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) GetItemCount(id string) (int64, error) {
|
||||
type Result struct {
|
||||
Result int64
|
||||
}
|
||||
var res Result
|
||||
db := repo.db.
|
||||
Raw("WITH RECURSIVE rec (id, parent_id) AS "+
|
||||
"(SELECT f.id, f.parent_id FROM file f WHERE f.id = ? "+
|
||||
"UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id) "+
|
||||
"SELECT count(rec.id) as result FROM rec", id).
|
||||
Scan(&res)
|
||||
if db.Error != nil {
|
||||
return 0, db.Error
|
||||
}
|
||||
return res.Result - 1, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) IsGrandChildOf(id string, ancestorID string) (bool, error) {
|
||||
type Result struct {
|
||||
Result bool
|
||||
}
|
||||
var res Result
|
||||
if db := repo.db.
|
||||
Raw("WITH RECURSIVE rec (id, parent_id) AS "+
|
||||
"(SELECT f.id, f.parent_id FROM file f WHERE f.id = ? "+
|
||||
"UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id) "+
|
||||
"SELECT count(rec.id) > 0 as result FROM rec WHERE rec.id = ?", ancestorID, id).
|
||||
Scan(&res); db.Error != nil {
|
||||
return false, db.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) GetSize(id string) (int64, error) {
|
||||
type Result struct {
|
||||
Result int64
|
||||
}
|
||||
var res Result
|
||||
db := repo.db.
|
||||
Raw("WITH RECURSIVE rec (id, parent_id) AS "+
|
||||
"(SELECT f.id, f.parent_id FROM file f WHERE f.id = ? "+
|
||||
"UNION SELECT f.id, f.parent_id FROM rec, file f WHERE f.parent_id = rec.id) "+
|
||||
"SELECT coalesce(sum((s.original->>'size')::int), 0) as result FROM snapshot s, rec "+
|
||||
"LEFT JOIN snapshot_file map ON rec.id = map.file_id WHERE map.snapshot_id = s.id", id).
|
||||
Scan(&res)
|
||||
if db.Error != nil {
|
||||
return res.Result, db.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) GrantUserPermission(id string, userID string, permission string) error {
|
||||
/* Grant permission to workspace */
|
||||
db := repo.db.Exec("INSERT INTO userpermission (id, user_id, resource_id, permission) "+
|
||||
"(SELECT ?, ?, w.id, 'viewer' FROM file f "+
|
||||
"INNER JOIN workspace w ON w.id = f.workspace_id AND f.id = ?) "+
|
||||
"ON CONFLICT DO NOTHING",
|
||||
helper.NewID(), userID, id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
|
||||
/* Grant 'viewer' permission to path files */
|
||||
path, err := repo.FindPath(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range path {
|
||||
db := repo.db.Exec("INSERT INTO userpermission (id, user_id, resource_id, permission) "+
|
||||
"VALUES (?, ?, ?, 'viewer') ON CONFLICT DO NOTHING",
|
||||
helper.NewID(), userID, f.GetID())
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
}
|
||||
|
||||
/* Grant the requested permission to tree files */
|
||||
tree, err := repo.FindTree(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range tree {
|
||||
db := repo.db.Exec("INSERT INTO userpermission (id, user_id, resource_id, permission) "+
|
||||
"VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?",
|
||||
helper.NewID(), userID, f.GetID(), permission, permission)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) RevokeUserPermission(id string, userID string) error {
|
||||
tree, err := repo.FindTree(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range tree {
|
||||
db := repo.db.Exec("DELETE FROM userpermission WHERE user_id = ? AND resource_id = ?", userID, f.GetID())
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) GrantGroupPermission(id string, groupID string, permission string) error {
|
||||
/* Grant permission to workspace */
|
||||
db := repo.db.Exec("INSERT INTO grouppermission (id, group_id, resource_id, permission) "+
|
||||
"(SELECT ?, ?, w.id, 'viewer' FROM file f "+
|
||||
"INNER JOIN workspace w ON w.id = f.workspace_id AND f.id = ?) "+
|
||||
"ON CONFLICT DO NOTHING",
|
||||
helper.NewID(), groupID, id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
|
||||
/* Grant 'viewer' permission to path files */
|
||||
path, err := repo.FindPath(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range path {
|
||||
db := repo.db.Exec("INSERT INTO grouppermission (id, group_id, resource_id, permission) "+
|
||||
"VALUES (?, ?, ?, 'viewer') ON CONFLICT DO NOTHING",
|
||||
helper.NewID(), groupID, f.GetID())
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
}
|
||||
|
||||
/* Grant the requested permission to tree files */
|
||||
tree, err := repo.FindTree(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range tree {
|
||||
db := repo.db.Exec("INSERT INTO grouppermission (id, group_id, resource_id, permission) "+
|
||||
"VALUES (?, ?, ?, ?) ON CONFLICT (group_id, resource_id) DO UPDATE SET permission = ?",
|
||||
helper.NewID(), groupID, f.GetID(), permission, permission)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) RevokeGroupPermission(id string, groupID string) error {
|
||||
tree, err := repo.FindTree(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, f := range tree {
|
||||
db := repo.db.Exec("DELETE FROM grouppermission WHERE group_id = ? AND resource_id = ?", groupID, f.GetID())
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *fileRepo) populateModelFields(entities []*fileEntity) error {
|
||||
for _, f := range entities {
|
||||
f.UserPermissions = make([]*userPermissionValue, 0)
|
||||
userPermissions, err := repo.permissionRepo.GetUserPermissions(f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range userPermissions {
|
||||
f.UserPermissions = append(f.UserPermissions, &userPermissionValue{
|
||||
UserID: p.UserID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
f.GroupPermissions = make([]*groupPermissionValue, 0)
|
||||
groupPermissions, err := repo.permissionRepo.GetGroupPermissions(f.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range groupPermissions {
|
||||
f.GroupPermissions = append(f.GroupPermissions, &groupPermissionValue{
|
||||
GroupID: p.GroupID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
snapshots, err := repo.snapshotRepo.findAllForFile(f.ID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
f.Snapshots = snapshots
|
||||
}
|
||||
return nil
|
||||
}
|
344
Voltaserve/api/repo/group_repo.go
Normal file
344
Voltaserve/api/repo/group_repo.go
Normal file
@ -0,0 +1,344 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/helper"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type GroupInsertOptions struct {
|
||||
ID string
|
||||
Name string
|
||||
OrganizationID string
|
||||
OwnerID string
|
||||
}
|
||||
|
||||
type GroupRepo interface {
|
||||
Insert(opts GroupInsertOptions) (model.Group, error)
|
||||
Find(id string) (model.Group, error)
|
||||
GetIDsForFile(fileID string) ([]string, error)
|
||||
GetIDsForUser(userID string) ([]string, error)
|
||||
GetIDsForOrganization(id string) ([]string, error)
|
||||
Save(group model.Group) error
|
||||
Delete(id string) error
|
||||
AddUser(id string, userID string) error
|
||||
RemoveMember(id string, userID string) error
|
||||
GetIDs() ([]string, error)
|
||||
GetMembers(id string) ([]model.User, error)
|
||||
GrantUserPermission(id string, userID string, permission string) error
|
||||
RevokeUserPermission(id string, userID string) error
|
||||
}
|
||||
|
||||
func NewGroupRepo() GroupRepo {
|
||||
return newGroupRepo()
|
||||
}
|
||||
|
||||
func NewGroup() model.Group {
|
||||
return &groupEntity{}
|
||||
}
|
||||
|
||||
type groupEntity struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
Name string `json:"name" gorm:"column:name"`
|
||||
OrganizationID string `json:"organizationId" gorm:"column:organization_id"`
|
||||
UserPermissions []*userPermissionValue `json:"userPermissions" gorm:"-"`
|
||||
GroupPermissions []*groupPermissionValue `json:"groupPermissions" gorm:"-"`
|
||||
Members []string `json:"members" gorm:"-"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*groupEntity) TableName() string {
|
||||
return "group"
|
||||
}
|
||||
|
||||
func (g *groupEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
g.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *groupEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
g.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetID() string {
|
||||
return g.ID
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetName() string {
|
||||
return g.Name
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetOrganizationID() string {
|
||||
return g.OrganizationID
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetUserPermissions() []model.CoreUserPermission {
|
||||
var res []model.CoreUserPermission
|
||||
for _, p := range g.UserPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetGroupPermissions() []model.CoreGroupPermission {
|
||||
var res []model.CoreGroupPermission
|
||||
for _, p := range g.GroupPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetUsers() []string {
|
||||
return g.Members
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetCreateTime() string {
|
||||
return g.CreateTime
|
||||
}
|
||||
|
||||
func (g *groupEntity) GetUpdateTime() *string {
|
||||
return g.UpdateTime
|
||||
}
|
||||
|
||||
func (g *groupEntity) SetName(name string) {
|
||||
g.Name = name
|
||||
}
|
||||
|
||||
func (g *groupEntity) SetUpdateTime(updateTime *string) {
|
||||
g.UpdateTime = updateTime
|
||||
}
|
||||
|
||||
type groupRepo struct {
|
||||
db *gorm.DB
|
||||
permissionRepo *permissionRepo
|
||||
}
|
||||
|
||||
func newGroupRepo() *groupRepo {
|
||||
return &groupRepo{
|
||||
db: infra.GetDb(),
|
||||
permissionRepo: newPermissionRepo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *groupRepo) Insert(opts GroupInsertOptions) (model.Group, error) {
|
||||
group := groupEntity{
|
||||
ID: opts.ID,
|
||||
Name: opts.Name,
|
||||
OrganizationID: opts.OrganizationID,
|
||||
}
|
||||
if db := repo.db.Save(&group); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res, err := repo.Find(opts.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) find(id string) (*groupEntity, error) {
|
||||
var res = groupEntity{}
|
||||
db := repo.db.Where("id = ?", id).First(&res)
|
||||
if db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewGroupNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) Find(id string) (model.Group, error) {
|
||||
group, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.populateModelFields([]*groupEntity{group}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) GetIDsForFile(fileID string) ([]string, error) {
|
||||
type Result struct {
|
||||
Result string
|
||||
}
|
||||
var results []Result
|
||||
db := repo.db.
|
||||
Raw(`SELECT DISTINCT g.id as result FROM "group" g INNER JOIN grouppermission p ON p.resource_id = ? WHERE p.group_id = g.id`, fileID).
|
||||
Scan(&results)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, v := range results {
|
||||
res = append(res, v.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) GetIDsForUser(userID string) ([]string, error) {
|
||||
type Result struct {
|
||||
Result string
|
||||
}
|
||||
var results []Result
|
||||
db := repo.db.Raw(`SELECT group_id from group_user WHERE user_id = ?`, userID).Scan(&results)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, v := range results {
|
||||
res = append(res, v.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) GetIDsForOrganization(id string) ([]string, error) {
|
||||
type Result struct {
|
||||
Result string
|
||||
}
|
||||
var results []Result
|
||||
db := repo.db.Raw(`SELECT id as result from "group" WHERE organization_id = ?`, id).Scan(&results)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, v := range results {
|
||||
res = append(res, v.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) Save(group model.Group) error {
|
||||
db := repo.db.Save(group)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) Delete(id string) error {
|
||||
db := repo.db.Exec(`DELETE FROM "group" WHERE id = ?`, id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM userpermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM grouppermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) AddUser(id string, userID string) error {
|
||||
db := repo.db.Exec("INSERT INTO group_user (group_id, user_id) VALUES (?, ?)", id, userID)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) RemoveMember(id string, userID string) error {
|
||||
db := repo.db.Exec("DELETE FROM group_user WHERE group_id = ? AND user_id = ?", id, userID)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) GetIDs() ([]string, error) {
|
||||
type Result struct {
|
||||
Result string
|
||||
}
|
||||
var results []Result
|
||||
db := repo.db.Raw(`SELECT id result FROM "group" ORDER BY create_time DESC`).Scan(&results)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, v := range results {
|
||||
res = append(res, v.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) GetMembers(id string) ([]model.User, error) {
|
||||
var entities []*userEntity
|
||||
db := repo.db.
|
||||
Raw(`SELECT DISTINCT u.* FROM "user" u INNER JOIN group_user gu ON u.id = gu.user_id WHERE gu.group_id = ?`, id).
|
||||
Scan(&entities)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.User
|
||||
for _, u := range entities {
|
||||
res = append(res, u)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) GrantUserPermission(id string, userID string, permission string) error {
|
||||
db := repo.db.Exec(
|
||||
"INSERT INTO userpermission (id, user_id, resource_id, permission) VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?",
|
||||
helper.NewID(), userID, id, permission, permission)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) RevokeUserPermission(id string, userID string) error {
|
||||
db := repo.db.Exec("DELETE FROM userpermission WHERE user_id = ? AND resource_id = ?", userID, id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *groupRepo) populateModelFields(groups []*groupEntity) error {
|
||||
for _, g := range groups {
|
||||
g.UserPermissions = make([]*userPermissionValue, 0)
|
||||
userPermissions, err := repo.permissionRepo.GetUserPermissions(g.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range userPermissions {
|
||||
g.UserPermissions = append(g.UserPermissions, &userPermissionValue{
|
||||
UserID: p.UserID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
g.GroupPermissions = make([]*groupPermissionValue, 0)
|
||||
groupPermissions, err := repo.permissionRepo.GetGroupPermissions(g.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range groupPermissions {
|
||||
g.GroupPermissions = append(g.GroupPermissions, &groupPermissionValue{
|
||||
GroupID: p.GroupID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
members, err := repo.GetMembers(g.ID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
g.Members = make([]string, 0)
|
||||
for _, u := range members {
|
||||
g.Members = append(g.Members, u.GetID())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
185
Voltaserve/api/repo/invitation_repo.go
Normal file
185
Voltaserve/api/repo/invitation_repo.go
Normal file
@ -0,0 +1,185 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/helper"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvitationInsertOptions struct {
|
||||
UserID string
|
||||
OrganizationID string
|
||||
Emails []string
|
||||
}
|
||||
|
||||
type InvitationRepo interface {
|
||||
Insert(opts InvitationInsertOptions) ([]model.Invitation, error)
|
||||
Find(id string) (model.Invitation, error)
|
||||
GetIncoming(email string) ([]model.Invitation, error)
|
||||
GetOutgoing(orgID string, userID string) ([]model.Invitation, error)
|
||||
Save(org model.Invitation) error
|
||||
Delete(id string) error
|
||||
}
|
||||
|
||||
func NewInvitationRepo() InvitationRepo {
|
||||
return newInvitationRepo()
|
||||
}
|
||||
|
||||
type invitationEntity struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
OrganizationID string `json:"organizationId" gorm:"column:organization_id"`
|
||||
OwnerID string `json:"ownerId" gorm:"column:owner_id"`
|
||||
Email string `json:"email" gorm:"column:email"`
|
||||
Status string `json:"status" gorm:"column:status"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*invitationEntity) TableName() string {
|
||||
return "invitation"
|
||||
}
|
||||
|
||||
func (i *invitationEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
i.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *invitationEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
i.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetID() string {
|
||||
return i.ID
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetOrganizationID() string {
|
||||
return i.OrganizationID
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetOwnerID() string {
|
||||
return i.OwnerID
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetEmail() string {
|
||||
return i.Email
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetStatus() string {
|
||||
return i.Status
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetCreateTime() string {
|
||||
return i.CreateTime
|
||||
}
|
||||
|
||||
func (i *invitationEntity) GetUpdateTime() *string {
|
||||
return i.UpdateTime
|
||||
}
|
||||
|
||||
func (i *invitationEntity) SetStatus(status string) {
|
||||
i.Status = status
|
||||
}
|
||||
|
||||
func (i *invitationEntity) SetUpdateTime(updateTime *string) {
|
||||
i.UpdateTime = updateTime
|
||||
}
|
||||
|
||||
type invitationRepo struct {
|
||||
db *gorm.DB
|
||||
userRepo *userRepo
|
||||
}
|
||||
|
||||
func newInvitationRepo() *invitationRepo {
|
||||
return &invitationRepo{
|
||||
db: infra.GetDb(),
|
||||
userRepo: newUserRepo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *invitationRepo) Insert(opts InvitationInsertOptions) ([]model.Invitation, error) {
|
||||
var res []model.Invitation
|
||||
for _, e := range opts.Emails {
|
||||
invitation := invitationEntity{
|
||||
ID: helper.NewID(),
|
||||
OrganizationID: opts.OrganizationID,
|
||||
OwnerID: opts.UserID,
|
||||
Email: e,
|
||||
Status: model.InvitationStatusPending,
|
||||
}
|
||||
if db := repo.db.Save(&invitation); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
i, err := repo.Find(invitation.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, i)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *invitationRepo) Find(id string) (model.Invitation, error) {
|
||||
var invitation = invitationEntity{}
|
||||
db := repo.db.Where("id = ?", id).First(&invitation)
|
||||
if db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewInvitationNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &invitation, nil
|
||||
}
|
||||
|
||||
func (repo *invitationRepo) GetIncoming(email string) ([]model.Invitation, error) {
|
||||
var invitations []*invitationEntity
|
||||
db := repo.db.
|
||||
Raw("SELECT * FROM invitation WHERE email = ? and status = 'pending' ORDER BY create_time DESC", email).
|
||||
Scan(&invitations)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.Invitation
|
||||
for _, inv := range invitations {
|
||||
res = append(res, inv)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *invitationRepo) GetOutgoing(orgID string, userID string) ([]model.Invitation, error) {
|
||||
var invitations []*invitationEntity
|
||||
db := repo.db.
|
||||
Raw("SELECT * FROM invitation WHERE organization_id = ? and owner_id = ? ORDER BY create_time DESC", orgID, userID).
|
||||
Scan(&invitations)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.Invitation
|
||||
for _, inv := range invitations {
|
||||
res = append(res, inv)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *invitationRepo) Save(org model.Invitation) error {
|
||||
db := repo.db.Save(org)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *invitationRepo) Delete(id string) error {
|
||||
db := repo.db.Exec("DELETE FROM invitation WHERE id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
319
Voltaserve/api/repo/organization_repo.go
Normal file
319
Voltaserve/api/repo/organization_repo.go
Normal file
@ -0,0 +1,319 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/helper"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type OrganizationInsertOptions struct {
|
||||
ID string
|
||||
Name string
|
||||
}
|
||||
|
||||
type OrganizationRepo interface {
|
||||
Insert(opts OrganizationInsertOptions) (model.Organization, error)
|
||||
Find(id string) (model.Organization, error)
|
||||
Save(org model.Organization) error
|
||||
Delete(id string) error
|
||||
GetIDs() ([]string, error)
|
||||
AddUser(id string, userID string) error
|
||||
RemoveMember(id string, userID string) error
|
||||
GetMembers(id string) ([]model.User, error)
|
||||
GetGroups(id string) ([]model.Group, error)
|
||||
GetOwnerCount(id string) (int64, error)
|
||||
GrantUserPermission(id string, userID string, permission string) error
|
||||
RevokeUserPermission(id string, userID string) error
|
||||
}
|
||||
|
||||
func NewOrganizationRepo() OrganizationRepo {
|
||||
return newOrganizationRepo()
|
||||
}
|
||||
|
||||
func NewOrganization() model.Organization {
|
||||
return &organizationEntity{}
|
||||
}
|
||||
|
||||
type organizationEntity struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
Name string `json:"name" gorm:"column:name"`
|
||||
UserPermissions []*userPermissionValue `json:"userPermissions" gorm:"-"`
|
||||
GroupPermissions []*groupPermissionValue `json:"groupPermissions" gorm:"-"`
|
||||
Members []string `json:"members" gorm:"-"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime,omitempty" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*organizationEntity) TableName() string {
|
||||
return "organization"
|
||||
}
|
||||
|
||||
func (o *organizationEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
o.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *organizationEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
o.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetID() string {
|
||||
return o.ID
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetName() string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetUserPermissions() []model.CoreUserPermission {
|
||||
var res []model.CoreUserPermission
|
||||
for _, p := range o.UserPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetGroupPermissions() []model.CoreGroupPermission {
|
||||
var res []model.CoreGroupPermission
|
||||
for _, p := range o.GroupPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetUsers() []string {
|
||||
return o.Members
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetCreateTime() string {
|
||||
return o.CreateTime
|
||||
}
|
||||
|
||||
func (o *organizationEntity) GetUpdateTime() *string {
|
||||
return o.UpdateTime
|
||||
}
|
||||
|
||||
func (o *organizationEntity) SetName(name string) {
|
||||
o.Name = name
|
||||
}
|
||||
|
||||
func (o *organizationEntity) SetUpdateTime(updateTime *string) {
|
||||
o.UpdateTime = updateTime
|
||||
}
|
||||
|
||||
type organizationRepo struct {
|
||||
db *gorm.DB
|
||||
groupRepo *groupRepo
|
||||
permissionRepo *permissionRepo
|
||||
}
|
||||
|
||||
func newOrganizationRepo() *organizationRepo {
|
||||
return &organizationRepo{
|
||||
db: infra.GetDb(),
|
||||
groupRepo: newGroupRepo(),
|
||||
permissionRepo: newPermissionRepo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) Insert(opts OrganizationInsertOptions) (model.Organization, error) {
|
||||
org := organizationEntity{
|
||||
ID: opts.ID,
|
||||
Name: opts.Name,
|
||||
}
|
||||
if db := repo.db.Save(&org); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res, err := repo.Find(opts.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) find(id string) (*organizationEntity, error) {
|
||||
var res = organizationEntity{}
|
||||
db := repo.db.Where("id = ?", id).First(&res)
|
||||
if db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewOrganizationNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) Find(id string) (model.Organization, error) {
|
||||
org, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.populateModelFields([]*organizationEntity{org}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return org, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) Save(org model.Organization) error {
|
||||
db := repo.db.Save(org)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) Delete(id string) error {
|
||||
db := repo.db.Exec("DELETE FROM organization WHERE id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM userpermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM grouppermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) GetIDs() ([]string, error) {
|
||||
type Result struct {
|
||||
Result string
|
||||
}
|
||||
var results []Result
|
||||
db := repo.db.Raw("SELECT id result FROM organization ORDER BY create_time DESC").Scan(&results)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, v := range results {
|
||||
res = append(res, v.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) AddUser(id string, userID string) error {
|
||||
db := repo.db.Exec("INSERT INTO organization_user (organization_id, user_id) VALUES (?, ?)", id, userID)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) RemoveMember(id string, userID string) error {
|
||||
db := repo.db.Exec("DELETE FROM organization_user WHERE organization_id = ? AND user_id = ?", id, userID)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) GetMembers(id string) ([]model.User, error) {
|
||||
var entities []*userEntity
|
||||
db := repo.db.
|
||||
Raw(`SELECT DISTINCT u.* FROM "user" u INNER JOIN organization_user ou ON u.id = ou.user_id WHERE ou.organization_id = ? ORDER BY u.full_name`, id).
|
||||
Scan(&entities)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.User
|
||||
for _, u := range entities {
|
||||
res = append(res, u)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) GetGroups(id string) ([]model.Group, error) {
|
||||
var entities []*groupEntity
|
||||
db := repo.db.
|
||||
Raw(`SELECT * FROM "group" g WHERE g.organization_id = ? ORDER BY g.name`, id).
|
||||
Scan(&entities)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
if err := repo.groupRepo.populateModelFields(entities); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []model.Group
|
||||
for _, g := range entities {
|
||||
res = append(res, g)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) GetOwnerCount(id string) (int64, error) {
|
||||
type Result struct {
|
||||
Result int64
|
||||
}
|
||||
var res Result
|
||||
db := repo.db.
|
||||
Raw("SELECT count(*) as result FROM userpermission WHERE resource_id = ? and permission = ?", id, model.PermissionOwner).
|
||||
Scan(&res)
|
||||
if db.Error != nil {
|
||||
return 0, db.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) GrantUserPermission(id string, userID string, permission string) error {
|
||||
db := repo.db.Exec(
|
||||
"INSERT INTO userpermission (id, user_id, resource_id, permission) VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?",
|
||||
helper.NewID(), userID, id, permission, permission)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) RevokeUserPermission(id string, userID string) error {
|
||||
db := repo.db.Exec("DELETE FROM userpermission WHERE user_id = ? AND resource_id = ?", userID, id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *organizationRepo) populateModelFields(organizations []*organizationEntity) error {
|
||||
for _, o := range organizations {
|
||||
o.UserPermissions = make([]*userPermissionValue, 0)
|
||||
userPermissions, err := repo.permissionRepo.GetUserPermissions(o.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range userPermissions {
|
||||
o.UserPermissions = append(o.UserPermissions, &userPermissionValue{
|
||||
UserID: p.UserID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
o.GroupPermissions = make([]*groupPermissionValue, 0)
|
||||
groupPermissions, err := repo.permissionRepo.GetGroupPermissions(o.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range groupPermissions {
|
||||
o.GroupPermissions = append(o.GroupPermissions, &groupPermissionValue{
|
||||
GroupID: p.GroupID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
members, err := repo.GetMembers(o.ID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
o.Members = make([]string, 0)
|
||||
for _, u := range members {
|
||||
o.Members = append(o.Members, u.GetID())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
102
Voltaserve/api/repo/permission_repo.go
Normal file
102
Voltaserve/api/repo/permission_repo.go
Normal file
@ -0,0 +1,102 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"voltaserve/infra"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserPermission struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
UserID string `json:"userId" gorm:"column:user_id"`
|
||||
ResourceID string `json:"resourceId" gorm:"column:resource_id"`
|
||||
Permission string `json:"permission" gorm:"column:permission"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
}
|
||||
|
||||
type GroupPermission struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
GroupID string `json:"groupId" gorm:"column:group_id"`
|
||||
ResourceID string `json:"resourceId" gorm:"column:resource_id"`
|
||||
Permission string `json:"permission" gorm:"column:permission"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
}
|
||||
|
||||
type PermissionRepo interface {
|
||||
GetUserPermissions(id string) ([]*UserPermission, error)
|
||||
GetGroupPermissions(id string) ([]*GroupPermission, error)
|
||||
}
|
||||
|
||||
func NewPermissionRepo() PermissionRepo {
|
||||
return newPermissionRepo()
|
||||
}
|
||||
|
||||
func (UserPermission) TableName() string {
|
||||
return "userpermission"
|
||||
}
|
||||
|
||||
func (GroupPermission) TableName() string {
|
||||
return "grouppermission"
|
||||
}
|
||||
|
||||
type userPermissionValue struct {
|
||||
UserID string `json:"userId,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (p userPermissionValue) GetUserID() string {
|
||||
return p.UserID
|
||||
}
|
||||
func (p userPermissionValue) GetValue() string {
|
||||
return p.Value
|
||||
}
|
||||
|
||||
type groupPermissionValue struct {
|
||||
GroupID string `json:"groupId,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
func (p groupPermissionValue) GetGroupID() string {
|
||||
return p.GroupID
|
||||
}
|
||||
func (p groupPermissionValue) GetValue() string {
|
||||
return p.Value
|
||||
}
|
||||
|
||||
type permissionRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func newPermissionRepo() *permissionRepo {
|
||||
return &permissionRepo{
|
||||
db: infra.GetDb(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *permissionRepo) GetUserPermissions(id string) ([]*UserPermission, error) {
|
||||
var res []*UserPermission
|
||||
if db := repo.db.
|
||||
Raw("SELECT * FROM userpermission WHERE resource_id = ?", id).
|
||||
Scan(&res); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return res, nil
|
||||
} else {
|
||||
return []*UserPermission{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *permissionRepo) GetGroupPermissions(id string) ([]*GroupPermission, error) {
|
||||
var res []*GroupPermission
|
||||
if db := repo.db.
|
||||
Raw("SELECT * FROM grouppermission WHERE resource_id = ?", id).
|
||||
Scan(&res); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return res, nil
|
||||
} else {
|
||||
return []*GroupPermission{}, nil
|
||||
}
|
||||
}
|
345
Voltaserve/api/repo/snapshot_repo.go
Normal file
345
Voltaserve/api/repo/snapshot_repo.go
Normal file
@ -0,0 +1,345 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SnapshotUpdateOptions struct {
|
||||
Original *model.S3Object
|
||||
Preview *model.S3Object
|
||||
Text *model.S3Object
|
||||
Thumbnail *model.Thumbnail
|
||||
Status string
|
||||
}
|
||||
|
||||
type SnapshotRepo interface {
|
||||
Find(id string) (model.Snapshot, error)
|
||||
Save(snapshot model.Snapshot) error
|
||||
Update(id string, opts SnapshotUpdateOptions) error
|
||||
MapWithFile(id string, fileID string) error
|
||||
DeleteMappingsForFile(fileID string) error
|
||||
FindAllDangling() ([]model.Snapshot, error)
|
||||
DeleteAllDangling() error
|
||||
GetLatestVersionForFile(fileID string) (int64, error)
|
||||
}
|
||||
|
||||
func NewSnapshotRepo() SnapshotRepo {
|
||||
return newSnapshotRepo()
|
||||
}
|
||||
|
||||
func NewSnapshot() model.Snapshot {
|
||||
return &snapshotEntity{}
|
||||
}
|
||||
|
||||
type snapshotEntity struct {
|
||||
ID string `json:"id" gorm:"column:id;size:36"`
|
||||
Version int64 `json:"version" gorm:"column:version"`
|
||||
Original datatypes.JSON `json:"original,omitempty" gorm:"column:original"`
|
||||
Preview datatypes.JSON `json:"preview,omitempty" gorm:"column:preview"`
|
||||
Text datatypes.JSON `json:"text,omitempty" gorm:"column:text"`
|
||||
Thumbnail datatypes.JSON `json:"thumbnail,omitempty" gorm:"column:thumbnail"`
|
||||
Status string `json:"status,omitempty" gorm:"column,status"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime,omitempty" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*snapshotEntity) TableName() string {
|
||||
return "snapshot"
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
s.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
s.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetID() string {
|
||||
return s.ID
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetVersion() int64 {
|
||||
return s.Version
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetOriginal() *model.S3Object {
|
||||
if s.Original.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.S3Object{}
|
||||
if err := json.Unmarshal([]byte(s.Original.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetPreview() *model.S3Object {
|
||||
if s.Preview.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.S3Object{}
|
||||
if err := json.Unmarshal([]byte(s.Preview.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetText() *model.S3Object {
|
||||
if s.Text.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.S3Object{}
|
||||
if err := json.Unmarshal([]byte(s.Text.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetThumbnail() *model.Thumbnail {
|
||||
if s.Thumbnail.String() == "" {
|
||||
return nil
|
||||
}
|
||||
var res = model.Thumbnail{}
|
||||
if err := json.Unmarshal([]byte(s.Thumbnail.String()), &res); err != nil {
|
||||
log.Fatal(err)
|
||||
return nil
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetStatus() string {
|
||||
return s.Status
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetID(id string) {
|
||||
s.ID = id
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetVersion(version int64) {
|
||||
s.Version = version
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetOriginal(m *model.S3Object) {
|
||||
if m == nil {
|
||||
s.Original = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Original.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetPreview(m *model.S3Object) {
|
||||
if m == nil {
|
||||
s.Preview = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Preview.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetText(m *model.S3Object) {
|
||||
if m == nil {
|
||||
s.Text = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Text.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetThumbnail(m *model.Thumbnail) {
|
||||
if m == nil {
|
||||
s.Thumbnail = nil
|
||||
} else {
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
if err := s.Thumbnail.UnmarshalJSON(b); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) SetStatus(status string) {
|
||||
s.Status = status
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasOriginal() bool {
|
||||
return s.Original != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasPreview() bool {
|
||||
return s.Preview != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasText() bool {
|
||||
return s.Text != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) HasThumbnail() bool {
|
||||
return s.Thumbnail != nil
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetCreateTime() string {
|
||||
return s.CreateTime
|
||||
}
|
||||
|
||||
func (s *snapshotEntity) GetUpdateTime() *string {
|
||||
return s.UpdateTime
|
||||
}
|
||||
|
||||
type snapshotRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func newSnapshotRepo() *snapshotRepo {
|
||||
return &snapshotRepo{
|
||||
db: infra.GetDb(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) find(id string) (*snapshotEntity, error) {
|
||||
var res snapshotEntity
|
||||
if db := repo.db.Where("id = ?", id).First(&res); db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewSnapshotNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) Find(id string) (model.Snapshot, error) {
|
||||
res, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) Save(snapshot model.Snapshot) error {
|
||||
if db := repo.db.Save(snapshot); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) Update(id string, opts SnapshotUpdateOptions) error {
|
||||
snapshot, err := repo.find(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.Thumbnail != nil {
|
||||
snapshot.SetThumbnail(opts.Thumbnail)
|
||||
}
|
||||
if opts.Original != nil {
|
||||
snapshot.SetOriginal(opts.Original)
|
||||
}
|
||||
if opts.Preview != nil {
|
||||
snapshot.SetPreview(opts.Preview)
|
||||
}
|
||||
if opts.Text != nil {
|
||||
snapshot.SetText(opts.Text)
|
||||
}
|
||||
if opts.Status != "" {
|
||||
snapshot.SetStatus(opts.Status)
|
||||
}
|
||||
if db := repo.db.Save(&snapshot); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) MapWithFile(id string, fileID string) error {
|
||||
if db := repo.db.Exec("INSERT INTO snapshot_file (snapshot_id, file_id) VALUES (?, ?)", id, fileID); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) DeleteMappingsForFile(fileID string) error {
|
||||
if db := repo.db.Exec("DELETE FROM snapshot_file WHERE file_id = ?", fileID); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) findAllForFile(fileID string) ([]*snapshotEntity, error) {
|
||||
var res []*snapshotEntity
|
||||
db := repo.db.
|
||||
Raw("SELECT * FROM snapshot s LEFT JOIN snapshot_file sf ON s.id = sf.snapshot_id WHERE sf.file_id = ? ORDER BY s.version", fileID).
|
||||
Scan(&res)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) FindAllDangling() ([]model.Snapshot, error) {
|
||||
var snapshots []*snapshotEntity
|
||||
db := repo.db.Raw("SELECT * FROM snapshot s LEFT JOIN snapshot_file sf ON s.id = sf.snapshot_id WHERE sf.snapshot_id IS NULL").Scan(&snapshots)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.Snapshot
|
||||
for _, s := range snapshots {
|
||||
res = append(res, s)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) DeleteAllDangling() error {
|
||||
if db := repo.db.Exec("DELETE FROM snapshot WHERE id IN (SELECT s.id FROM (SELECT * FROM snapshot) s LEFT JOIN snapshot_file sf ON s.id = sf.snapshot_id WHERE sf.snapshot_id IS NULL)"); db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *snapshotRepo) GetLatestVersionForFile(fileID string) (int64, error) {
|
||||
type Result struct {
|
||||
Result int64
|
||||
}
|
||||
var res Result
|
||||
if db := repo.db.
|
||||
Raw("SELECT coalesce(max(s.version), 0) + 1 result FROM snapshot s LEFT JOIN snapshot_file map ON s.id = map.snapshot_id WHERE map.file_id = ?", fileID).
|
||||
Scan(&res); db.Error != nil {
|
||||
return 0, db.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
121
Voltaserve/api/repo/user_repo.go
Normal file
121
Voltaserve/api/repo/user_repo.go
Normal file
@ -0,0 +1,121 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserRepo interface {
|
||||
Find(id string) (model.User, error)
|
||||
FindByEmail(email string) (model.User, error)
|
||||
FindAll() ([]model.User, error)
|
||||
}
|
||||
|
||||
func NewUserRepo() UserRepo {
|
||||
return newUserRepo()
|
||||
}
|
||||
|
||||
func NewUser() model.User {
|
||||
return &userEntity{}
|
||||
}
|
||||
|
||||
type userEntity struct {
|
||||
ID string `json:"id" gorm:"column:id"`
|
||||
FullName string `json:"fullName" gorm:"column:full_name"`
|
||||
Username string `json:"username" gorm:"column:username"`
|
||||
Email string `json:"email" gorm:"column:email"`
|
||||
Picture *string `json:"picture" gorm:"column:picture"`
|
||||
IsEmailConfirmed bool `json:"isEmailConfirmed" gorm:"column:is_email_confirmed"`
|
||||
PasswordHash string `json:"passwordHash" gorm:"column:password_hash"`
|
||||
RefreshTokenValue *string `json:"refreshTokenValue" gorm:"column:refresh_token_value"`
|
||||
RefreshTokenValidTo *int64 `json:"refreshTokenValidTo" gorm:"column:refresh_token_valid_to"`
|
||||
ResetPasswordToken *string `json:"resetPasswordToken" gorm:"column:reset_password_token"`
|
||||
EmailConfirmationToken *string `json:"emailConfirmationToken" gorm:"column:email_confirmation_token"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (userEntity) TableName() string {
|
||||
return "user"
|
||||
}
|
||||
|
||||
func (u userEntity) GetID() string {
|
||||
return u.ID
|
||||
}
|
||||
|
||||
func (u userEntity) GetFullName() string {
|
||||
return u.FullName
|
||||
}
|
||||
|
||||
func (u userEntity) GetUsername() string {
|
||||
return u.Username
|
||||
}
|
||||
|
||||
func (u userEntity) GetEmail() string {
|
||||
return u.Email
|
||||
}
|
||||
|
||||
func (u userEntity) GetPicture() *string {
|
||||
return u.Picture
|
||||
}
|
||||
|
||||
func (u userEntity) GetIsEmailConfirmed() bool {
|
||||
return u.IsEmailConfirmed
|
||||
}
|
||||
|
||||
func (u userEntity) GetCreateTime() string {
|
||||
return u.CreateTime
|
||||
}
|
||||
|
||||
func (u userEntity) GetUpdateTime() *string {
|
||||
return u.UpdateTime
|
||||
}
|
||||
|
||||
type userRepo struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func newUserRepo() *userRepo {
|
||||
return &userRepo{
|
||||
db: infra.GetDb(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *userRepo) Find(id string) (model.User, error) {
|
||||
var res = userEntity{}
|
||||
db := repo.db.Where("id = ?", id).First(&res)
|
||||
if db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewUserNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *userRepo) FindByEmail(email string) (model.User, error) {
|
||||
var res = userEntity{}
|
||||
db := repo.db.Where("email = ?", email).First(&res)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *userRepo) FindAll() ([]model.User, error) {
|
||||
var entities []*userEntity
|
||||
db := repo.db.Raw(`select * from "user"`).Scan(&entities)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
var res []model.User
|
||||
for _, u := range entities {
|
||||
res = append(res, u)
|
||||
}
|
||||
return res, nil
|
||||
}
|
319
Voltaserve/api/repo/workspace_repo.go
Normal file
319
Voltaserve/api/repo/workspace_repo.go
Normal file
@ -0,0 +1,319 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
"voltaserve/errorpkg"
|
||||
"voltaserve/helper"
|
||||
"voltaserve/infra"
|
||||
"voltaserve/model"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type WorkspaceInsertOptions struct {
|
||||
ID string
|
||||
Name string
|
||||
StorageCapacity int64
|
||||
Image *string
|
||||
OrganizationID string
|
||||
RootID string
|
||||
Bucket string
|
||||
}
|
||||
|
||||
type WorkspaceRepo interface {
|
||||
Insert(opts WorkspaceInsertOptions) (model.Workspace, error)
|
||||
Find(id string) (model.Workspace, error)
|
||||
UpdateName(id string, name string) (model.Workspace, error)
|
||||
UpdateStorageCapacity(id string, storageCapacity int64) (model.Workspace, error)
|
||||
UpdateRootID(id string, rootNodeID string) error
|
||||
Delete(id string) error
|
||||
GetIDs() ([]string, error)
|
||||
GetIDsByOrganization(orgID string) ([]string, error)
|
||||
GrantUserPermission(id string, userID string, permission string) error
|
||||
}
|
||||
|
||||
func NewWorkspaceRepo() WorkspaceRepo {
|
||||
return newWorkspaceRepo()
|
||||
}
|
||||
|
||||
func NewWorkspace() model.Workspace {
|
||||
return &workspaceEntity{}
|
||||
}
|
||||
|
||||
type workspaceEntity struct {
|
||||
ID string `json:"id," gorm:"column:id;size:36"`
|
||||
Name string `json:"name" gorm:"column:name;size:255"`
|
||||
StorageCapacity int64 `json:"storageCapacity" gorm:"column:storage_capacity"`
|
||||
RootID string `json:"rootId" gorm:"column:root_id;size:36"`
|
||||
OrganizationID string `json:"organizationId" gorm:"column:organization_id;size:36"`
|
||||
UserPermissions []*userPermissionValue `json:"userPermissions" gorm:"-"`
|
||||
GroupPermissions []*groupPermissionValue `json:"groupPermissions" gorm:"-"`
|
||||
Bucket string `json:"bucket" gorm:"column:bucket;size:255"`
|
||||
CreateTime string `json:"createTime" gorm:"column:create_time"`
|
||||
UpdateTime *string `json:"updateTime,omitempty" gorm:"column:update_time"`
|
||||
}
|
||||
|
||||
func (*workspaceEntity) TableName() string {
|
||||
return "workspace"
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) BeforeCreate(*gorm.DB) (err error) {
|
||||
w.CreateTime = time.Now().UTC().Format(time.RFC3339)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) BeforeSave(*gorm.DB) (err error) {
|
||||
timeNow := time.Now().UTC().Format(time.RFC3339)
|
||||
w.UpdateTime = &timeNow
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetID() string {
|
||||
return w.ID
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetName() string {
|
||||
return w.Name
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetStorageCapacity() int64 {
|
||||
return w.StorageCapacity
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetRootID() string {
|
||||
return w.RootID
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetOrganizationID() string {
|
||||
return w.OrganizationID
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetUserPermissions() []model.CoreUserPermission {
|
||||
var res []model.CoreUserPermission
|
||||
for _, p := range w.UserPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetGroupPermissions() []model.CoreGroupPermission {
|
||||
var res []model.CoreGroupPermission
|
||||
for _, p := range w.GroupPermissions {
|
||||
res = append(res, p)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetBucket() string {
|
||||
return w.Bucket
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetCreateTime() string {
|
||||
return w.CreateTime
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) GetUpdateTime() *string {
|
||||
return w.UpdateTime
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) SetName(name string) {
|
||||
w.Name = name
|
||||
}
|
||||
|
||||
func (w *workspaceEntity) SetUpdateTime(updateTime *string) {
|
||||
w.UpdateTime = updateTime
|
||||
}
|
||||
|
||||
type workspaceRepo struct {
|
||||
db *gorm.DB
|
||||
permissionRepo *permissionRepo
|
||||
}
|
||||
|
||||
func newWorkspaceRepo() *workspaceRepo {
|
||||
return &workspaceRepo{
|
||||
db: infra.GetDb(),
|
||||
permissionRepo: newPermissionRepo(),
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) Insert(opts WorkspaceInsertOptions) (model.Workspace, error) {
|
||||
var id string
|
||||
if len(opts.ID) > 0 {
|
||||
id = opts.ID
|
||||
} else {
|
||||
id = helper.NewID()
|
||||
}
|
||||
workspace := workspaceEntity{
|
||||
ID: id,
|
||||
Name: opts.Name,
|
||||
StorageCapacity: opts.StorageCapacity,
|
||||
RootID: opts.RootID,
|
||||
OrganizationID: opts.OrganizationID,
|
||||
Bucket: opts.Bucket,
|
||||
}
|
||||
if db := repo.db.Save(&workspace); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.populateModelFields([]*workspaceEntity{res}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) find(id string) (*workspaceEntity, error) {
|
||||
var res = workspaceEntity{}
|
||||
db := repo.db.Where("id = ?", id).First(&res)
|
||||
if db.Error != nil {
|
||||
if errors.Is(db.Error, gorm.ErrRecordNotFound) {
|
||||
return nil, errorpkg.NewWorkspaceNotFoundError(db.Error)
|
||||
} else {
|
||||
return nil, errorpkg.NewInternalServerError(db.Error)
|
||||
}
|
||||
}
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) Find(id string) (model.Workspace, error) {
|
||||
workspace, err := repo.find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := repo.populateModelFields([]*workspaceEntity{workspace}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return workspace, err
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) UpdateName(id string, name string) (model.Workspace, error) {
|
||||
workspace, err := repo.find(id)
|
||||
if err != nil {
|
||||
return &workspaceEntity{}, err
|
||||
}
|
||||
workspace.Name = name
|
||||
if db := repo.db.Save(&workspace); db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res, err := repo.Find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) UpdateStorageCapacity(id string, storageCapacity int64) (model.Workspace, error) {
|
||||
workspace, err := repo.find(id)
|
||||
if err != nil {
|
||||
return &workspaceEntity{}, err
|
||||
}
|
||||
workspace.StorageCapacity = storageCapacity
|
||||
db := repo.db.Save(&workspace)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res, err := repo.Find(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) UpdateRootID(id string, rootNodeID string) error {
|
||||
db := repo.db.Exec("UPDATE workspace SET root_id = ? WHERE id = ?", rootNodeID, id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) Delete(id string) error {
|
||||
db := repo.db.Exec("DELETE FROM workspace WHERE id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM userpermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
db = repo.db.Exec("DELETE FROM grouppermission WHERE resource_id = ?", id)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) GetIDs() ([]string, error) {
|
||||
type IDResult struct {
|
||||
Result string
|
||||
}
|
||||
var ids []IDResult
|
||||
db := repo.db.Raw("SELECT id result FROM workspace ORDER BY create_time DESC").Scan(&ids)
|
||||
if db.Error != nil {
|
||||
return []string{}, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, id := range ids {
|
||||
res = append(res, id.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) GetIDsByOrganization(orgID string) ([]string, error) {
|
||||
type IDResult struct {
|
||||
Result string
|
||||
}
|
||||
var ids []IDResult
|
||||
db := repo.db.
|
||||
Raw("SELECT id result FROM workspace WHERE organization_id = ? ORDER BY create_time DESC", orgID).
|
||||
Scan(&ids)
|
||||
if db.Error != nil {
|
||||
return nil, db.Error
|
||||
}
|
||||
res := []string{}
|
||||
for _, id := range ids {
|
||||
res = append(res, id.Result)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) GrantUserPermission(id string, userID string, permission string) error {
|
||||
db := repo.db.Exec(
|
||||
"INSERT INTO userpermission (id, user_id, resource_id, permission) VALUES (?, ?, ?, ?) ON CONFLICT (user_id, resource_id) DO UPDATE SET permission = ?",
|
||||
helper.NewID(), userID, id, permission, permission)
|
||||
if db.Error != nil {
|
||||
return db.Error
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *workspaceRepo) populateModelFields(workspaces []*workspaceEntity) error {
|
||||
for _, w := range workspaces {
|
||||
w.UserPermissions = make([]*userPermissionValue, 0)
|
||||
userPermissions, err := repo.permissionRepo.GetUserPermissions(w.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range userPermissions {
|
||||
w.UserPermissions = append(w.UserPermissions, &userPermissionValue{
|
||||
UserID: p.UserID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
w.GroupPermissions = make([]*groupPermissionValue, 0)
|
||||
groupPermissions, err := repo.permissionRepo.GetGroupPermissions(w.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, p := range groupPermissions {
|
||||
w.GroupPermissions = append(w.GroupPermissions, &groupPermissionValue{
|
||||
GroupID: p.GroupID,
|
||||
Value: p.Permission,
|
||||
})
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user