You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
4.9 KiB

10 years ago
10 years ago
  1. package types
  2. import (
  3. "fmt"
  4. . "github.com/tendermint/tendermint/common"
  5. )
  6. //------------------------------------------------------------------------------------------------
  7. var (
  8. GlobalPermissionsAddress = Zero256[:20]
  9. GlobalPermissionsAddress256 = Zero256
  10. DougAddress = append([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, []byte("THISISDOUG")...)
  11. DougAddress256 = LeftPadWord256(DougAddress)
  12. )
  13. // A particular permission
  14. type PermFlag uint64
  15. // Base permission references are like unix (the index is already bit shifted)
  16. const (
  17. Root PermFlag = 1 << iota // 1
  18. Send // 2
  19. Call // 4
  20. CreateContract // 8
  21. CreateAccount // 16
  22. Bond // 32
  23. Name // 64
  24. NumBasePermissions uint = 7 // NOTE Adjust this too.
  25. TopBasePermFlag PermFlag = 1 << (NumBasePermissions - 1)
  26. AllBasePermFlags PermFlag = TopBasePermFlag | (TopBasePermFlag - 1)
  27. AllPermFlags PermFlag = AllBasePermFlags | AllSNativePermFlags
  28. DefaultBasePermFlags PermFlag = Send | Call | CreateContract | CreateAccount | Bond | Name
  29. )
  30. var (
  31. ZeroBasePermissions = BasePermissions{0, 0}
  32. ZeroAccountPermissions = AccountPermissions{
  33. Base: ZeroBasePermissions,
  34. }
  35. DefaultAccountPermissions = AccountPermissions{
  36. Base: BasePermissions{
  37. Perms: DefaultBasePermFlags,
  38. SetBit: AllPermFlags,
  39. },
  40. Roles: []string{},
  41. }
  42. )
  43. //---------------------------------------------------------------------------------------------
  44. // Base chain permissions struct
  45. type BasePermissions struct {
  46. // bit array with "has"/"doesn't have" for each permission
  47. Perms PermFlag `json:"perms"`
  48. // bit array with "set"/"not set" for each permission (not-set should fall back to global)
  49. SetBit PermFlag `json:"set"`
  50. }
  51. // Get a permission value. ty should be a power of 2.
  52. // ErrValueNotSet is returned if the permission's set bit is off,
  53. // and should be caught by caller so the global permission can be fetched
  54. func (p *BasePermissions) Get(ty PermFlag) (bool, error) {
  55. if ty == 0 {
  56. return false, ErrInvalidPermission(ty)
  57. }
  58. if p.SetBit&ty == 0 {
  59. return false, ErrValueNotSet(ty)
  60. }
  61. return p.Perms&ty > 0, nil
  62. }
  63. // Set a permission bit. Will set the permission's set bit to true.
  64. func (p *BasePermissions) Set(ty PermFlag, value bool) error {
  65. if ty == 0 {
  66. return ErrInvalidPermission(ty)
  67. }
  68. p.SetBit |= ty
  69. if value {
  70. p.Perms |= ty
  71. } else {
  72. p.Perms &= ^ty
  73. }
  74. return nil
  75. }
  76. // Set the permission's set bit to false
  77. func (p *BasePermissions) Unset(ty PermFlag) error {
  78. if ty == 0 {
  79. return ErrInvalidPermission(ty)
  80. }
  81. p.SetBit &= ^ty
  82. return nil
  83. }
  84. // Check if the permission is set
  85. func (p *BasePermissions) IsSet(ty PermFlag) bool {
  86. if ty == 0 {
  87. return false
  88. }
  89. return p.SetBit&ty > 0
  90. }
  91. func (p BasePermissions) String() string {
  92. return fmt.Sprintf("Base: %b; Set: %b", p.Perms, p.SetBit)
  93. }
  94. //---------------------------------------------------------------------------------------------
  95. type AccountPermissions struct {
  96. Base BasePermissions `json:"base"`
  97. Roles []string `json:"roles"`
  98. }
  99. // Returns true if the role is found
  100. func (aP *AccountPermissions) HasRole(role string) bool {
  101. role = string(LeftPadBytes([]byte(role), 32))
  102. for _, r := range aP.Roles {
  103. if r == role {
  104. return true
  105. }
  106. }
  107. return false
  108. }
  109. // Returns true if the role is added, and false if it already exists
  110. func (aP *AccountPermissions) AddRole(role string) bool {
  111. role = string(LeftPadBytes([]byte(role), 32))
  112. for _, r := range aP.Roles {
  113. if r == role {
  114. return false
  115. }
  116. }
  117. aP.Roles = append(aP.Roles, role)
  118. return true
  119. }
  120. // Returns true if the role is removed, and false if it is not found
  121. func (aP *AccountPermissions) RmRole(role string) bool {
  122. role = string(LeftPadBytes([]byte(role), 32))
  123. for i, r := range aP.Roles {
  124. if r == role {
  125. post := []string{}
  126. if len(aP.Roles) > i+1 {
  127. post = aP.Roles[i+1:]
  128. }
  129. aP.Roles = append(aP.Roles[:i], post...)
  130. return true
  131. }
  132. }
  133. return false
  134. }
  135. //--------------------------------------------------------------------------------
  136. func PermFlagToString(pf PermFlag) (perm string, err error) {
  137. switch pf {
  138. case Root:
  139. perm = "root"
  140. case Send:
  141. perm = "send"
  142. case Call:
  143. perm = "call"
  144. case CreateContract:
  145. perm = "create_contract"
  146. case CreateAccount:
  147. perm = "create_account"
  148. case Bond:
  149. perm = "bond"
  150. case Name:
  151. perm = "name"
  152. default:
  153. err = fmt.Errorf("Unknown permission flag %b", pf)
  154. }
  155. return
  156. }
  157. func PermStringToFlag(perm string) (pf PermFlag, err error) {
  158. switch perm {
  159. case "root":
  160. pf = Root
  161. case "send":
  162. pf = Send
  163. case "call":
  164. pf = Call
  165. case "create_contract":
  166. pf = CreateContract
  167. case "create_account":
  168. pf = CreateAccount
  169. case "bond":
  170. pf = Bond
  171. case "name":
  172. pf = Name
  173. default:
  174. err = fmt.Errorf("Unknown permission %s", perm)
  175. }
  176. return
  177. }