@@ -3,7 +3,8 @@ package blobstore
33import (
44 "fmt"
55 "net/http"
6- "time"
6+ "os"
7+ "strings"
78
89 "github.com/Dewberry/s3api/auth"
910 "github.com/Dewberry/s3api/utils"
@@ -14,6 +15,7 @@ import (
1415)
1516
1617func (s3Ctrl * S3Controller ) KeyExists (bucket string , key string ) (bool , error ) {
18+
1719 _ , err := s3Ctrl .S3Svc .HeadObject (& s3.HeadObjectInput {
1820 Bucket : aws .String (bucket ),
1921 Key : aws .String (key ),
@@ -33,23 +35,23 @@ func (s3Ctrl *S3Controller) KeyExists(bucket string, key string) (bool, error) {
3335}
3436
3537// function that will get the most recently uploaded file in a prefix
36- func (s3Ctrl * S3Controller ) getMostRecentModTime (bucket , prefix string ) (time.Time , error ) {
37- // Initialize a time variable to store the most recent modification time
38- var mostRecent time.Time
38+ // func (s3Ctrl *S3Controller) getMostRecentModTime(bucket, prefix string, permissions []string, fullAccess bool ) (time.Time, error) {
39+ // // Initialize a time variable to store the most recent modification time
40+ // var mostRecent time.Time
3941
40- // Call GetList to retrieve the list of objects with the specified prefix
41- response , err := s3Ctrl .GetList (bucket , prefix , false )
42- if err != nil {
43- return time.Time {}, err
44- }
45- // Iterate over the returned objects to find the most recent modification time
46- for _ , item := range response .Contents {
47- if item .LastModified != nil && item .LastModified .After (mostRecent ) {
48- mostRecent = * item .LastModified
49- }
50- }
51- return mostRecent , nil
52- }
42+ // // Call GetList to retrieve the list of objects with the specified prefix
43+ // response, err := s3Ctrl.GetList(bucket, prefix, false)
44+ // if err != nil {
45+ // return time.Time{}, err
46+ // }
47+ // // Iterate over the returned objects to find the most recent modification time
48+ // for _, item := range response.Contents {
49+ // if item.LastModified != nil && item.LastModified.After(mostRecent) {
50+ // mostRecent = *item.LastModified
51+ // }
52+ // }
53+ // return mostRecent, nil
54+ // }
5355
5456func arrayContains (a string , arr []string ) bool {
5557 for _ , b := range arr {
@@ -80,8 +82,13 @@ func isIdenticalArray(array1, array2 []string) bool {
8082 return true
8183}
8284
83- func (bh * BlobHandler ) CheckUserS3WritePermission (c echo.Context , bucket , key string ) (int , error ) {
85+ func (bh * BlobHandler ) CheckUserS3Permission (c echo.Context , bucket , prefix string , permissions [] string ) (int , error ) {
8486 if bh .Config .AuthLevel > 0 {
87+ initAuth := os .Getenv ("INIT_AUTH" )
88+ if initAuth == "0" {
89+ errMsg := fmt .Errorf ("this requires authentication information that is unavailable when authorization is disabled. Please enable authorization to use this functionality" )
90+ return http .StatusForbidden , errMsg
91+ }
8592 claims , ok := c .Get ("claims" ).(* auth.Claims )
8693 if ! ok {
8794 return http .StatusInternalServerError , fmt .Errorf ("could not get claims from request context" )
@@ -91,13 +98,54 @@ func (bh *BlobHandler) CheckUserS3WritePermission(c echo.Context, bucket, key st
9198
9299 // Check for required roles
93100 isLimitedWriter := utils .StringInSlice (bh .Config .LimitedWriterRoleName , roles )
101+ // Ensure the prefix ends with a slash
102+ if ! strings .HasSuffix (prefix , "/" ) {
103+ prefix += "/"
104+ }
94105
95106 // We assume if someone is limited_writer, they should never be admin or super_writer
96107 if isLimitedWriter {
97- if ! bh .DB .CheckUserPermission (ue , "write" , fmt . Sprintf ( "/%s/%s" , bucket , key ) ) {
108+ if ! bh .DB .CheckUserPermission (ue , bucket , prefix , permissions ) {
98109 return http .StatusForbidden , fmt .Errorf ("forbidden" )
99110 }
100111 }
101112 }
102113 return 0 , nil
103114}
115+
116+ func (bh * BlobHandler ) GetUserS3ReadListPermission (c echo.Context , bucket string ) ([]string , bool , error ) {
117+ permissions := make ([]string , 0 )
118+
119+ if bh .Config .AuthLevel > 0 {
120+ initAuth := os .Getenv ("INIT_AUTH" )
121+ if initAuth == "0" {
122+ errMsg := fmt .Errorf ("this endpoint requires authentication information that is unavailable when authorization is disabled. Please enable authorization to use this functionality" )
123+ return permissions , false , errMsg
124+ }
125+ fullAccess := false
126+ claims , ok := c .Get ("claims" ).(* auth.Claims )
127+ if ! ok {
128+ return permissions , fullAccess , fmt .Errorf ("could not get claims from request context" )
129+ }
130+ roles := claims .RealmAccess ["roles" ]
131+
132+ // Check if user has the limited reader role
133+ isLimitedReader := utils .StringInSlice (bh .Config .LimitedReaderRoleName , roles )
134+
135+ // If user is not a limited reader, assume they have full read access
136+ if ! isLimitedReader {
137+ fullAccess = true // Indicating full access
138+ return permissions , fullAccess , nil
139+ }
140+
141+ // If user is a limited reader, fetch specific permissions
142+ ue := claims .Email
143+ permissions , err := bh .DB .GetUserAccessiblePrefixes (ue , bucket , []string {"read" , "write" })
144+ if err != nil {
145+ return permissions , fullAccess , err
146+ }
147+ return permissions , fullAccess , nil
148+ }
149+
150+ return permissions , true , nil
151+ }
0 commit comments