github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/native/permissions.go (about) 1 package native 2 3 import ( 4 "fmt" 5 6 "github.com/hyperledger/burrow/execution/engine" 7 8 "github.com/hyperledger/burrow/acm" 9 "github.com/hyperledger/burrow/crypto" 10 "github.com/hyperledger/burrow/permission" 11 ) 12 13 var Permissions = New().MustContract("Permissions", 14 `* Interface for managing Secure Native authorizations. 15 * @dev This interface describes the functions exposed by the native permissions layer in burrow. 16 `, 17 Function{ 18 Comment: ` 19 * @notice Adds a role to an account 20 * @param _account account address 21 * @param _role role name 22 * @return _result whether role was added 23 `, 24 PermFlag: permission.AddRole, 25 F: addRole, 26 }, 27 Function{ 28 Comment: ` 29 * @notice Removes a role from an account 30 * @param _account account address 31 * @param _role role name 32 * @return _result whether role was removed 33 `, 34 PermFlag: permission.RemoveRole, 35 F: removeRole, 36 }, 37 Function{ 38 Comment: ` 39 * @notice Indicates whether an account has a role 40 * @param _account account address 41 * @param _role role name 42 * @return _result whether account has role 43 `, 44 PermFlag: permission.HasRole, 45 F: hasRole, 46 }, 47 Function{ 48 Comment: ` 49 * @notice Sets the permission flags for an account. Makes them explicitly set (on or off). 50 * @param _account account address 51 * @param _permission the base permissions flags to set for the account 52 * @param _set whether to set or unset the permissions flags at the account level 53 * @return _result is the permission flag that was set as uint64 54 `, 55 PermFlag: permission.SetBase, 56 F: setBase, 57 }, 58 Function{ 59 Comment: ` 60 * @notice Unsets the permissions flags for an account. Causes permissions being unset to fall through to global permissions. 61 * @param _account account address 62 * @param _permission the permissions flags to unset for the account 63 * @return _result is the permission flag that was unset as uint64 64 `, 65 PermFlag: permission.UnsetBase, 66 F: unsetBase, 67 }, 68 Function{ 69 Comment: ` 70 * @notice Indicates whether an account has a subset of permissions set 71 * @param _account account address 72 * @param _permission the permissions flags (mask) to check whether enabled against base permissions for the account 73 * @return _result is whether account has the passed permissions flags set 74 `, 75 PermFlag: permission.HasBase, 76 F: hasBase, 77 }, 78 Function{Comment: ` 79 * @notice Sets the global (default) permissions flags for the entire chain 80 * @param _permission the permissions flags to set 81 * @param _set whether to set (or unset) the permissions flags 82 * @return _result is the permission flag that was set as uint64 83 `, 84 PermFlag: permission.SetGlobal, 85 F: setGlobal, 86 }, 87 ) 88 89 type hasBaseArgs struct { 90 Account crypto.Address 91 Permission uint64 92 } 93 94 type hasBaseRets struct { 95 Result bool 96 } 97 98 func hasBase(ctx Context, args hasBaseArgs) (hasBaseRets, error) { 99 permN := permission.PermFlag(args.Permission) // already shifted 100 if !permN.IsValid() { 101 return hasBaseRets{}, permission.ErrInvalidPermission(permN) 102 } 103 hasPermission, err := engine.HasPermission(ctx.State, args.Account, permN) 104 if err != nil { 105 return hasBaseRets{}, err 106 } 107 ctx.Logger.Trace.Log("function", "hasBase", 108 "address", args.Account.String(), 109 "perm_flag", fmt.Sprintf("%b", permN), 110 "has_permission", hasPermission) 111 return hasBaseRets{Result: hasPermission}, nil 112 } 113 114 type setBaseArgs struct { 115 Account crypto.Address 116 Permission uint64 117 Set bool 118 } 119 120 type setBaseRets struct { 121 Result uint64 122 } 123 124 func setBase(ctx Context, args setBaseArgs) (setBaseRets, error) { 125 permFlag := permission.PermFlag(args.Permission) 126 if !permFlag.IsValid() { 127 return setBaseRets{}, permission.ErrInvalidPermission(permFlag) 128 } 129 err := engine.UpdateAccount(ctx.State, args.Account, func(acc *acm.Account) error { 130 err := acc.Permissions.Base.Set(permFlag, args.Set) 131 return err 132 }) 133 if err != nil { 134 return setBaseRets{}, err 135 } 136 ctx.Logger.Trace.Log("function", "setBase", "address", args.Account.String(), 137 "permission_flag", fmt.Sprintf("%b", permFlag), 138 "permission_value", args.Permission) 139 return setBaseRets{Result: uint64(permFlag)}, nil 140 } 141 142 type unsetBaseArgs struct { 143 Account crypto.Address 144 Permission uint64 145 } 146 147 type unsetBaseRets struct { 148 Result uint64 149 } 150 151 func unsetBase(ctx Context, args unsetBaseArgs) (unsetBaseRets, error) { 152 permFlag := permission.PermFlag(args.Permission) 153 if !permFlag.IsValid() { 154 return unsetBaseRets{}, permission.ErrInvalidPermission(permFlag) 155 } 156 err := engine.UpdateAccount(ctx.State, args.Account, func(acc *acm.Account) error { 157 return acc.Permissions.Base.Unset(permFlag) 158 }) 159 if err != nil { 160 return unsetBaseRets{}, err 161 } 162 ctx.Logger.Trace.Log("function", "unsetBase", "address", args.Account.String(), 163 "perm_flag", fmt.Sprintf("%b", permFlag), 164 "permission_flag", fmt.Sprintf("%b", permFlag)) 165 166 return unsetBaseRets{Result: uint64(permFlag)}, nil 167 } 168 169 type setGlobalArgs struct { 170 Permission uint64 171 Set bool 172 } 173 174 type setGlobalRets struct { 175 Result uint64 176 } 177 178 func setGlobal(ctx Context, args setGlobalArgs) (setGlobalRets, error) { 179 permFlag := permission.PermFlag(args.Permission) 180 if !permFlag.IsValid() { 181 return setGlobalRets{}, permission.ErrInvalidPermission(permFlag) 182 } 183 err := engine.UpdateAccount(ctx.State, acm.GlobalPermissionsAddress, func(acc *acm.Account) error { 184 return acc.Permissions.Base.Set(permFlag, args.Set) 185 }) 186 if err != nil { 187 return setGlobalRets{}, err 188 } 189 ctx.Logger.Trace.Log("function", "setGlobal", 190 "permission_flag", fmt.Sprintf("%b", permFlag), 191 "permission_value", args.Set) 192 return setGlobalRets{Result: uint64(permFlag)}, nil 193 } 194 195 type hasRoleArgs struct { 196 Account crypto.Address 197 Role string 198 } 199 200 type hasRoleRets struct { 201 Result bool 202 } 203 204 func hasRole(ctx Context, args hasRoleArgs) (hasRoleRets, error) { 205 acc, err := engine.MustAccount(ctx.State, args.Account) 206 if err != nil { 207 return hasRoleRets{}, err 208 } 209 hasRole := acc.Permissions.HasRole(args.Role) 210 ctx.Logger.Trace.Log("function", "hasRole", "address", args.Account.String(), 211 "role", args.Role, 212 "has_role", hasRole) 213 return hasRoleRets{Result: hasRole}, nil 214 } 215 216 type addRoleArgs struct { 217 Account crypto.Address 218 Role string 219 } 220 221 type addRoleRets struct { 222 Result bool 223 } 224 225 func addRole(ctx Context, args addRoleArgs) (addRoleRets, error) { 226 ret := addRoleRets{} 227 err := engine.UpdateAccount(ctx.State, args.Account, func(account *acm.Account) error { 228 ret.Result = account.Permissions.AddRole(args.Role) 229 return nil 230 }) 231 if err != nil { 232 return ret, err 233 } 234 ctx.Logger.Trace.Log("function", "addRole", "address", args.Account.String(), 235 "role", args.Role, 236 "role_added", ret.Result) 237 return ret, nil 238 } 239 240 type removeRoleArgs struct { 241 Account crypto.Address 242 Role string 243 } 244 245 type removeRoleRets struct { 246 Result bool 247 } 248 249 func removeRole(ctx Context, args removeRoleArgs) (removeRoleRets, error) { 250 ret := removeRoleRets{} 251 err := engine.UpdateAccount(ctx.State, args.Account, func(account *acm.Account) error { 252 ret.Result = account.Permissions.RemoveRole(args.Role) 253 return nil 254 }) 255 if err != nil { 256 return ret, err 257 } 258 ctx.Logger.Trace.Log("function", "removeRole", "address", args.Account.String(), 259 "role", args.Role, 260 "role_removed", ret.Result) 261 return ret, nil 262 }