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.

175 lines
4.2 KiB

10 years ago
10 years ago
10 years ago
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. DefaultBBPB = Send | Call | CreateContract | CreateAccount | Bond | Name
  25. NumBasePermissions uint = 7
  26. TopBasePermission PermFlag = 1 << (NumBasePermissions - 1)
  27. AllSet PermFlag = (1 << 63) - 1 + (1 << 63)
  28. )
  29. //---------------------------------------------------------------------------------------------
  30. // Base chain permissions struct
  31. type BasePermissions struct {
  32. // bit array with "has"/"doesn't have" for each permission
  33. Perms PermFlag
  34. // bit array with "set"/"not set" for each permission (not-set should fall back to global)
  35. SetBit PermFlag
  36. }
  37. func NewBasePermissions() *BasePermissions {
  38. return &BasePermissions{0, 0}
  39. }
  40. // Get a permission value. ty should be a power of 2.
  41. // ErrValueNotSet is returned if the permission's set bit is off,
  42. // and should be caught by caller so the global permission can be fetched
  43. func (p *BasePermissions) Get(ty PermFlag) (bool, error) {
  44. if ty == 0 {
  45. return false, ErrInvalidPermission(ty)
  46. }
  47. if p.SetBit&ty == 0 {
  48. return false, ErrValueNotSet(ty)
  49. }
  50. return p.Perms&ty > 0, nil
  51. }
  52. // Set a permission bit. Will set the permission's set bit to true.
  53. func (p *BasePermissions) Set(ty PermFlag, value bool) error {
  54. if ty == 0 {
  55. return ErrInvalidPermission(ty)
  56. }
  57. p.SetBit |= ty
  58. if value {
  59. p.Perms |= ty
  60. } else {
  61. p.Perms &= ^ty
  62. }
  63. return nil
  64. }
  65. // Set the permission's set bit to false
  66. func (p *BasePermissions) Unset(ty PermFlag) error {
  67. if ty == 0 {
  68. return ErrInvalidPermission(ty)
  69. }
  70. p.SetBit &= ^ty
  71. return nil
  72. }
  73. func (p *BasePermissions) Copy() *BasePermissions {
  74. if p == nil {
  75. return nil
  76. }
  77. return &BasePermissions{
  78. Perms: p.Perms,
  79. SetBit: p.SetBit,
  80. }
  81. }
  82. func (p *BasePermissions) String() string {
  83. return fmt.Sprintf("Base: %b; Set: %b", p.Perms, p.SetBit)
  84. }
  85. //---------------------------------------------------------------------------------------------
  86. type AccountPermissions struct {
  87. Base *BasePermissions
  88. Roles []string
  89. }
  90. func NewAccountPermissions() *AccountPermissions {
  91. return &AccountPermissions{
  92. Base: NewBasePermissions(),
  93. Roles: []string{},
  94. }
  95. }
  96. // Returns true if the role is found
  97. func (aP *AccountPermissions) HasRole(role string) bool {
  98. role = string(LeftPadBytes([]byte(role), 32))
  99. for _, r := range aP.Roles {
  100. if r == role {
  101. return true
  102. }
  103. }
  104. return false
  105. }
  106. // Returns true if the role is added, and false if it already exists
  107. func (aP *AccountPermissions) AddRole(role string) bool {
  108. role = string(LeftPadBytes([]byte(role), 32))
  109. for _, r := range aP.Roles {
  110. if r == role {
  111. return false
  112. }
  113. }
  114. aP.Roles = append(aP.Roles, role)
  115. return true
  116. }
  117. // Returns true if the role is removed, and false if it is not found
  118. func (aP *AccountPermissions) RmRole(role string) bool {
  119. role = string(LeftPadBytes([]byte(role), 32))
  120. for i, r := range aP.Roles {
  121. if r == role {
  122. post := []string{}
  123. if len(aP.Roles) > i+1 {
  124. post = aP.Roles[i+1:]
  125. }
  126. aP.Roles = append(aP.Roles[:i], post...)
  127. return true
  128. }
  129. }
  130. return false
  131. }
  132. func (aP *AccountPermissions) Copy() *AccountPermissions {
  133. if aP == nil {
  134. return nil
  135. }
  136. r := make([]string, len(aP.Roles))
  137. copy(r, aP.Roles)
  138. return &AccountPermissions{
  139. Base: aP.Base.Copy(),
  140. Roles: r,
  141. }
  142. }
  143. func NewDefaultAccountPermissions() *AccountPermissions {
  144. return &AccountPermissions{
  145. Base: &BasePermissions{
  146. Perms: DefaultBBPB,
  147. SetBit: AllSet,
  148. },
  149. Roles: []string{},
  150. }
  151. }