RowIter implements the interface sql.ExecSourceRel.
(ctx *sql.Context, r sql.Row)
| 57 | |
| 58 | // RowIter implements the interface sql.ExecSourceRel. |
| 59 | func (c *AlterRole) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) { |
| 60 | var userRole auth.Role |
| 61 | var role auth.Role |
| 62 | auth.LockRead(func() { |
| 63 | userRole = auth.GetRole(ctx.Client().User) |
| 64 | role = auth.GetRole(c.Name) |
| 65 | }) |
| 66 | if !userRole.IsValid() { |
| 67 | return nil, errors.Errorf(`role "%s" does not exist`, userRole.Name) |
| 68 | } |
| 69 | if !role.IsValid() { |
| 70 | return nil, errors.Errorf(`role "%s" does not exist`, c.Name) |
| 71 | } |
| 72 | |
| 73 | if role.IsSuperUser && !userRole.IsSuperUser { |
| 74 | // Only superusers can modify other superusers |
| 75 | // TODO: grab the actual error message |
| 76 | return nil, errors.Errorf(`role "%s" does not have permission to alter role "%s"`, userRole.Name, role.Name) |
| 77 | } else if !userRole.IsSuperUser && !userRole.CanCreateRoles && role.ID() != userRole.ID() { |
| 78 | // A role may only modify itself if it doesn't have the ability to create roles |
| 79 | // TODO: allow non-role-creating roles to only modify their own password, and grab actual error message |
| 80 | return nil, errors.Errorf(`role "%s" does not have permission to alter role "%s"`, userRole.Name, role.Name) |
| 81 | } |
| 82 | for optionName, optionValue := range c.Options { |
| 83 | switch optionName { |
| 84 | case "BYPASSRLS": |
| 85 | if !userRole.IsSuperUser { |
| 86 | // TODO: grab the actual error message |
| 87 | return nil, errors.Errorf(`role "%s" does not have permission to alter role "%s"`, userRole.Name, role.Name) |
| 88 | } |
| 89 | role.CanBypassRowLevelSecurity = true |
| 90 | case "CONNECTION_LIMIT": |
| 91 | role.ConnectionLimit = optionValue.(int32) |
| 92 | case "CREATEDB": |
| 93 | role.CanCreateDB = true |
| 94 | case "CREATEROLE": |
| 95 | role.CanCreateRoles = true |
| 96 | case "INHERIT": |
| 97 | role.InheritPrivileges = true |
| 98 | case "LOGIN": |
| 99 | role.CanLogin = true |
| 100 | case "NOBYPASSRLS": |
| 101 | if !userRole.IsSuperUser { |
| 102 | // TODO: grab the actual error message |
| 103 | return nil, errors.Errorf(`role "%s" does not have permission to alter role "%s"`, userRole.Name, role.Name) |
| 104 | } |
| 105 | role.CanBypassRowLevelSecurity = false |
| 106 | case "NOCREATEDB": |
| 107 | role.CanCreateDB = false |
| 108 | case "NOCREATEROLE": |
| 109 | role.CanCreateRoles = false |
| 110 | case "NOINHERIT": |
| 111 | role.InheritPrivileges = false |
| 112 | case "NOLOGIN": |
| 113 | role.CanLogin = false |
| 114 | case "NOREPLICATION": |
| 115 | if !userRole.IsSuperUser { |
| 116 | // TODO: grab the actual error message |
nothing calls this directly
no test coverage detected