github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/web/sharings/readonly.go (about) 1 package sharings 2 3 import ( 4 "errors" 5 "net/http" 6 "strconv" 7 8 "github.com/cozy/cozy-stack/model/sharing" 9 "github.com/cozy/cozy-stack/pkg/jsonapi" 10 "github.com/cozy/cozy-stack/web/middlewares" 11 "github.com/labstack/echo/v4" 12 ) 13 14 // AddReadOnly is used to downgrade a read-write member to read-only 15 func AddReadOnly(c echo.Context) error { 16 inst := middlewares.GetInstance(c) 17 sharingID := c.Param("sharing-id") 18 s, err := sharing.FindSharing(inst, sharingID) 19 if err != nil { 20 return wrapErrors(err) 21 } 22 _, err = checkCreatePermissions(c, s) 23 if err != nil { 24 // It can be a delegated call from a member on an open sharing to the owner 25 if err = hasSharingWritePermissions(c); err != nil { 26 return err 27 } 28 } 29 index, err := strconv.Atoi(c.Param("index")) 30 if err != nil { 31 return jsonapi.InvalidParameter("index", err) 32 } 33 if index == 0 || index >= len(s.Members) { 34 return jsonapi.InvalidParameter("index", errors.New("Invalid index")) 35 } 36 if s.Owner { 37 if err = s.AddReadOnlyFlag(inst, index); err != nil { 38 return wrapErrors(err) 39 } 40 go s.NotifyRecipients(inst, nil) 41 } else { 42 if err = s.DelegateAddReadOnlyFlag(inst, index); err != nil { 43 return wrapErrors(err) 44 } 45 } 46 return c.NoContent(http.StatusNoContent) 47 } 48 49 // DowngradeToReadOnly is used to receive the credentials for pushing last changes 50 // on an instance of a recipient before going to read-only mode 51 func DowngradeToReadOnly(c echo.Context) error { 52 inst := middlewares.GetInstance(c) 53 sharingID := c.Param("sharing-id") 54 s, err := sharing.FindSharing(inst, sharingID) 55 if err != nil { 56 return wrapErrors(err) 57 } 58 var creds sharing.APICredentials 59 if _, err = jsonapi.Bind(c.Request().Body, &creds); err != nil { 60 return jsonapi.BadJSON() 61 } 62 if err = s.DowngradeToReadOnly(inst, &creds); err != nil { 63 return wrapErrors(err) 64 } 65 return c.NoContent(http.StatusNoContent) 66 } 67 68 // RemoveReadOnly is used to give read-write to a member that had the read-only flag 69 func RemoveReadOnly(c echo.Context) error { 70 inst := middlewares.GetInstance(c) 71 sharingID := c.Param("sharing-id") 72 s, err := sharing.FindSharing(inst, sharingID) 73 if err != nil { 74 return wrapErrors(err) 75 } 76 _, err = checkCreatePermissions(c, s) 77 if err != nil { 78 // It can be a delegated call from a member on an open sharing to the owner 79 if err = hasSharingWritePermissions(c); err != nil { 80 return err 81 } 82 } 83 index, err := strconv.Atoi(c.Param("index")) 84 if err != nil { 85 return jsonapi.InvalidParameter("index", err) 86 } 87 if index == 0 || index >= len(s.Members) { 88 return jsonapi.InvalidParameter("index", errors.New("Invalid index")) 89 } 90 if s.Owner { 91 if err = s.RemoveReadOnlyFlag(inst, index); err != nil { 92 return wrapErrors(err) 93 } 94 go s.NotifyRecipients(inst, nil) 95 } else { 96 if err = s.DelegateRemoveReadOnlyFlag(inst, index); err != nil { 97 return wrapErrors(err) 98 } 99 } 100 return c.NoContent(http.StatusNoContent) 101 } 102 103 // UpgradeToReadWrite is used to receive the credentials for pushing updates on 104 // an instance of a recipient that was in read-only mode 105 func UpgradeToReadWrite(c echo.Context) error { 106 inst := middlewares.GetInstance(c) 107 sharingID := c.Param("sharing-id") 108 s, err := sharing.FindSharing(inst, sharingID) 109 if err != nil { 110 return wrapErrors(err) 111 } 112 var creds sharing.APICredentials 113 if _, err = jsonapi.Bind(c.Request().Body, &creds); err != nil { 114 return jsonapi.BadJSON() 115 } 116 if err = s.UpgradeToReadWrite(inst, &creds); err != nil { 117 return wrapErrors(err) 118 } 119 return c.NoContent(http.StatusNoContent) 120 }