mirror of
https://github.com/versity/versitygw.git
synced 2026-09-24 08:54:47 +00:00
feat: add IAM Role CRUD
Adds `CreateRole`, `GetRole`, `ListRoles`, `DeleteRole`, and `UpdateAssumeRolePolicy` to the standalone IAM service, following the same controller/storage patterns established for users. Both the internal filesystem/S3-backed store and the Vault-backed store implement the new `Storer` methods, with role-specific indexing and lookup helpers mirroring the existing user ones. Role creation requires a trust policy, passed as `AssumeRolePolicyDocument`. A trust policy is a distinct kind of IAM policy document that governs who (or what) is allowed to assume a role, rather than what actions the role itself is permitted to perform. Its grammar is effectively the inverse of an identity policy: `Principal` is required, `Action`/`NotAction` values must carry the `sts:` prefix, and `Resource`/`NotResource` are forbidden. This is implemented in `iamapi/policy/trust.go` as a new validation path alongside the existing identity-policy validation, and is reused by `UpdateAssumeRolePolicy` when replacing a role's trust policy. Also fixes user name uniqueness enforcement to be case-insensitive, matching AWS IAM behavior, and applies the same case-insensitive handling to role names. The internal store now maintains lowercase name indexes for both users and roles, and the Vault store resolves the canonical stored key via a case-insensitive list-and-compare fallback since Vault's KV paths are case-sensitive.
This commit is contained in:
+29
-1
@@ -113,7 +113,7 @@ func (e Error) XMLBody(requestID string) []byte {
|
||||
type errorXML struct {
|
||||
Type ErrorType
|
||||
Code string
|
||||
Message string
|
||||
Message string `xml:",omitempty"`
|
||||
}
|
||||
|
||||
var errorCodeResponse = map[ErrorCode]Error{
|
||||
@@ -345,10 +345,22 @@ func NoSuchEntityAccessKey(accessKeyID string) Error {
|
||||
return newSenderError("NoSuchEntity", fmt.Sprintf("The Access Key with id %s cannot be found", accessKeyID), http.StatusNotFound)
|
||||
}
|
||||
|
||||
func EntityAlreadyExistsRole(roleName string) Error {
|
||||
return newSenderError("EntityAlreadyExists", fmt.Sprintf("Role with name %s already exists.", roleName), http.StatusConflict)
|
||||
}
|
||||
|
||||
func NoSuchEntityRole(roleName string) Error {
|
||||
return newSenderError("NoSuchEntity", fmt.Sprintf("The role with name %s cannot be found.", roleName), http.StatusNotFound)
|
||||
}
|
||||
|
||||
func AccessKeysLimitExceeded(maxKeys int) Error {
|
||||
return newSenderError("LimitExceeded", fmt.Sprintf("Cannot exceed quota for AccessKeysPerUser: %d", maxKeys), http.StatusConflict)
|
||||
}
|
||||
|
||||
func TrustPolicySizeLimitExceeded(maxBytes int) Error {
|
||||
return newSenderError("LimitExceeded", fmt.Sprintf("Cannot exceed quota for ACLSizePerRole: %d", maxBytes), http.StatusConflict)
|
||||
}
|
||||
|
||||
func ValidationError(message string) Error {
|
||||
return newSenderError("ValidationError", message, http.StatusBadRequest)
|
||||
}
|
||||
@@ -417,6 +429,22 @@ func InvalidCharset(field string) Error {
|
||||
return ValidationError(fmt.Sprintf("The specified value for %s is invalid. It must contain only printable ASCII characters.", field))
|
||||
}
|
||||
|
||||
func InvalidDescriptionCharset(field string) Error {
|
||||
return ValidationError(fmt.Sprintf("1 validation error detected: Value at '%s' failed to satisfy constraint: Member must satisfy regular expression pattern: [\\u0009\\u000A\\u000D\\u0020-\\u007E\\u00A1-\\u00FF]*", field))
|
||||
}
|
||||
|
||||
func MaxSessionDurationTooLow() Error {
|
||||
return ValidationError("1 validation error detected: Value at 'maxSessionDuration' failed to satisfy constraint: Member must have value greater than or equal to 3600")
|
||||
}
|
||||
|
||||
func MaxSessionDurationTooHigh() Error {
|
||||
return ValidationError("1 validation error detected: Value at 'maxSessionDuration' failed to satisfy constraint: Member must have value less than or equal to 43200")
|
||||
}
|
||||
|
||||
func MalformedInput() Error {
|
||||
return newSenderError("MalformedInput", "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
func MalformedPolicyDocument(message string) Error {
|
||||
return newSenderError("MalformedPolicyDocument", message, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user