@ -635,6 +635,8 @@ type folderK8sHandler struct {
// #TODO check if it makes more sense to move this to FolderAPIBuilder
accesscontrolService accesscontrol . Service
userService user . Service
// #TODO remove after we handle the nested folder case
folderService folder . Service
}
//-----------------------------------------------------------------------------------------
@ -648,6 +650,7 @@ func newFolderK8sHandler(hs *HTTPServer) *folderK8sHandler {
clientConfigProvider : hs . clientConfigProvider ,
accesscontrolService : hs . accesscontrolService ,
userService : hs . userService ,
folderService : hs . folderService ,
}
}
@ -700,7 +703,7 @@ func (fk8s *folderK8sHandler) createFolder(c *contextmodel.ReqContext) {
}
fk8s . accesscontrolService . ClearUserPermissionCache ( c . SignedInUser )
folderDTO , err := fk8s . newToFolderDto ( c , * out )
folderDTO , err := fk8s . newToFolderDto ( c , * out , c . SignedInUser . GetOrgID ( ) )
if err != nil {
fk8s . writeError ( c , err )
return
@ -795,10 +798,11 @@ func (fk8s *folderK8sHandler) writeError(c *contextmodel.ReqContext, err error)
errhttp . Write ( c . Req . Context ( ) , err , c . Resp )
}
func ( fk8s * folderK8sHandler ) newToFolderDto ( c * contextmodel . ReqContext , item unstructured . Unstructured ) ( dtos . Folder , error ) {
func ( fk8s * folderK8sHandler ) newToFolderDto ( c * contextmodel . ReqContext , item unstructured . Unstructured , orgID int64 ) ( dtos . Folder , error ) {
// #TODO revisit how/where we get orgID
ctx := c . Req . Context ( )
f := internalfolders . UnstructuredToLegacyFolder ( item )
f := internalfolders . UnstructuredToLegacyFolder ( item , orgID )
fDTO , err := internalfolders . UnstructuredToLegacyFolderDTO ( item )
if err != nil {
@ -817,8 +821,8 @@ func (fk8s *folderK8sHandler) newToFolderDto(c *contextmodel.ReqContext, item un
return userID , nil
}
toDTO := func ( f * folder . Folder , checkCanView bool ) ( dtos . Folder , error ) {
g , err := guardian . NewByFolder ( c . Req . Context ( ) , f , c . SignedInUser . GetOrgID ( ) , c . SignedInUser )
toDTO := func ( fold * folder . Folder , checkCanView bool ) ( dtos . Folder , error ) {
g , err := guardian . NewByFolder ( c . Req . Context ( ) , fold , c . SignedInUser . GetOrgID ( ) , c . SignedInUser )
if err != nil {
return dtos . Folder { } , err
}
@ -830,6 +834,8 @@ func (fk8s *folderK8sHandler) newToFolderDto(c *contextmodel.ReqContext, item un
// Finding creator and last updater of the folder
updater , creator := anonString , anonString
// #TODO refactor the various conversions of the folder so that we either set created by in folder.Folder or
// we convert from unstructured to folder DTO without an intermediate conversion to folder.Folder
if len ( fDTO . CreatedBy ) > 0 {
id , err := toID ( fDTO . CreatedBy )
if err != nil {
@ -845,7 +851,7 @@ func (fk8s *folderK8sHandler) newToFolderDto(c *contextmodel.ReqContext, item un
updater = fk8s . getUserLogin ( ctx , id )
}
acMetadata , _ := fk8s . getFolderACMetadata ( c , f )
acMetadata , _ := fk8s . getFolderACMetadata ( c , fold )
if checkCanView {
canView , _ := g . CanView ( )
@ -865,6 +871,9 @@ func (fk8s *folderK8sHandler) newToFolderDto(c *contextmodel.ReqContext, item un
fDTO . CreatedBy = creator
fDTO . UpdatedBy = updater
fDTO . AccessControl = acMetadata
fDTO . OrgID = f . OrgID
// #TODO version doesn't seem to be used--confirm or set it properly
fDTO . Version = 1
return * fDTO , nil
}
@ -875,24 +884,54 @@ func (fk8s *folderK8sHandler) newToFolderDto(c *contextmodel.ReqContext, item un
return dtos . Folder { } , err
}
// TODO: handle parents
/ *
parents , err := fk8s . folderService . GetParents ( ctx , folder . GetParentsQuery { UID : f . UID , OrgID : f . OrgID } )
parents := [ ] * folder . Folder { }
if folderDTO . ParentUID != "" {
parents , err = fk8s . folderService . GetParents (
c . Req . Context ( ) ,
folder . GetParentsQuery {
UID : folderDTO . UID ,
OrgID : folderDTO . OrgID ,
} )
if err != nil {
// log the error instead of failing
fk8s . log . Error ( "failed to fetch folder parents" , "folder" , f . UID , "org" , f . OrgID , "error" , err )
return dtos . Folder { } , err
}
}
folderDTO . Parents = make ( [ ] dtos . Folder , 0 , len ( parents ) )
for _ , f := range parents {
DTO , err := toDTO ( f , true )
if err != nil {
// fk8s.log.Error("failed to convert folder to DTO", "folder", f.UID, "org", f.OrgID, "error", err)
continue
// #TODO refactor so that we have just one function for converting to folder DTO
toParentDTO := func ( fold * folder . Folder , checkCanView bool ) ( dtos . Folder , error ) {
g , err := guardian . NewByFolder ( c . Req . Context ( ) , fold , c . SignedInUser . GetOrgID ( ) , c . SignedInUser )
if err != nil {
return dtos . Folder { } , err
}
if checkCanView {
canView , _ := g . CanView ( )
if ! canView {
return dtos . Folder {
UID : REDACTED ,
Title : REDACTED ,
} , nil
}
folderDTO . Parents = append ( folderDTO . Parents , DTO )
}
* /
metrics . MFolderIDsAPICount . WithLabelValues ( metrics . NewToFolderDTO ) . Inc ( )
return dtos . Folder {
UID : fold . UID ,
Title : fold . Title ,
URL : fold . URL ,
} , nil
}
folderDTO . Parents = make ( [ ] dtos . Folder , 0 , len ( parents ) )
for _ , f := range parents {
DTO , err := toParentDTO ( f , true )
if err != nil {
// #TODO add logging
// fk8s.log.Error("failed to convert folder to DTO", "folder", f.UID, "org", f.OrgID, "error", err)
continue
}
folderDTO . Parents = append ( folderDTO . Parents , DTO )
}
return folderDTO , nil
}
@ -914,20 +953,24 @@ func (fk8s *folderK8sHandler) getFolderACMetadata(c *contextmodel.ReqContext, f
return nil , nil
}
folderIDs := map [ string ] bool { f . UID : true }
// TODO: handle parents
/ *
parents , err := fk8s . folderService . GetParents ( c . Req . Context ( ) , folder . GetParentsQuery { UID : f . UID , OrgID : c . SignedInUser . GetOrgID ( ) } )
var err error
parents := [ ] * folder . Folder { }
if f . ParentUID != "" {
parents , err = fk8s . folderService . GetParents (
c . Req . Context ( ) ,
folder . GetParentsQuery {
UID : f . UID ,
OrgID : c . SignedInUser . GetOrgID ( ) ,
} )
if err != nil {
return nil , err
}
}
folderIDs := map [ string ] bool { f . UID : true }
for _ , p := range parents {
folderIDs [ p . UID ] = true
}
* /
folderIDs := map [ string ] bool { f . UID : true }
for _ , p := range parents {
folderIDs [ p . UID ] = true
}
allMetadata := getMultiAccessControlMetadata ( c , dashboards . ScopeFoldersPrefix , folderIDs )
metadata := map [ string ] bool { }