public async Task <bool> PolicyExistsAsync(string bucketName, StatementItem statement) { if (string.IsNullOrEmpty(bucketName)) { throw new ArgumentNullException(nameof(bucketName)); } if (statement == null || string.IsNullOrEmpty(statement.Effect) || (statement.Action == null || statement.Action.Count == 0) || (statement.Resource == null || statement.Resource.Count == 0)) { throw new ArgumentNullException(nameof(StatementItem)); } PolicyInfo info = await GetPolicyAsync(bucketName); if (info.Statement == null || info.Statement.Count == 0) { return(false); } if (statement.Resource.Count > 1) { throw new Exception("Only support one resource."); } foreach (var item in info.Statement) { bool result = true; bool findSource = false; if (item.Resource.Count == 1) { if ((IsRootResource(bucketName, item.Resource[0]) && IsRootResource(bucketName, statement.Resource[0])) || item.Resource[0].Equals(statement.Resource[0])) { findSource = true; } } else { foreach (var sourceitem in item.Resource) { if (sourceitem.Equals(statement.Resource[0]) && item.Effect.Equals(statement.Effect, StringComparison.OrdinalIgnoreCase)) { findSource = true; } } } if (!findSource) { continue; } //验证规则 if (!item.Effect.Equals(statement.Effect)) { //访问权限 continue; } if (item.Action.Count < statement.Action.Count) { //动作,如果存在的条目数量少于要验证的,false continue; } foreach (var actionItem in statement.Action) { //验证action if (!item.Action.Any(p => p.Equals(actionItem, StringComparison.OrdinalIgnoreCase))) { result = false; } } if (result) { return(result); } } return(false); }
public async Task <AccessMode> GetBucketAclAsync(string bucketName) { bool FindAction(List <string> actions, string input) { if (actions != null && actions.Count > 0 && actions.Exists(p => p.Equals(input, StringComparison.OrdinalIgnoreCase))) { return(true); } return(false); } PolicyInfo info = await GetPolicyAsync(bucketName); if (info == null) { return(AccessMode.Default); } if (info.Statement == null || info.Statement.Count == 0) { return(AccessMode.Private); } List <StatementItem> statements = UnpackResource(info.Statement); bool isPublicRead = false; bool isPublicWrite = false; foreach (var item in statements) { if (!IsRootResource(bucketName, item.Resource[0])) { continue; } if (item.Action == null || item.Action.Count == 0) { continue; } if (item.Effect.Equals("Allow", StringComparison.OrdinalIgnoreCase)) { if (FindAction(item.Action, "*")) { return(AccessMode.PublicReadWrite); } if (FindAction(item.Action, "s3:GetObject")) { isPublicRead = true; } if (FindAction(item.Action, "s3:PutObject")) { isPublicWrite = true; } } if (isPublicRead && isPublicWrite) { return(AccessMode.PublicReadWrite); } } //结果 if (isPublicRead && !isPublicWrite) { return(AccessMode.PublicRead); } else if (isPublicRead && isPublicWrite) { return(AccessMode.PublicReadWrite); } else if (!isPublicRead && isPublicWrite) { return(AccessMode.Private); } else { return(AccessMode.Private); } }
/// <summary> /// 设置存储桶的权限 /// </summary> /// <param name="bucketName">存储桶名称。</param> /// <param name="statements">权限条目</param> /// <returns></returns> public async Task <bool> SetPolicyAsync(string bucketName, List <StatementItem> statements) { if (string.IsNullOrEmpty(bucketName)) { throw new ArgumentNullException(nameof(bucketName)); } if (statements == null || statements.Count == 0) { throw new ArgumentNullException(nameof(PolicyInfo)); } List <StatementItem> oldStatements = null; List <StatementItem> addStatements = statements; List <StatementItem> tempStatements = new List <StatementItem>(); //获取原有的 PolicyInfo info = await GetPolicyAsync(bucketName); if (info.Statement == null) { info.Statement = new List <StatementItem>(); } else { oldStatements = UnpackResource(info.Statement); } //解析要添加的条目,将包含多条Resource的条目解析为仅包含一条条目的数据 statements = UnpackResource(statements); //验证要添加的数据 foreach (var addItem in statements) { if (!addItem.Effect.Equals("Allow", StringComparison.OrdinalIgnoreCase) && !addItem.Effect.Equals("Deny", StringComparison.OrdinalIgnoreCase)) { throw new Exception("Add statement effect only support 'Allow' or 'Deny'."); } if (addItem.Action == null || addItem.Action.Count == 0) { throw new Exception("Add statement action can not null"); } if (addItem.Resource == null || addItem.Resource.Count == 0) { throw new Exception("Add statement resource can not null"); } if (addItem.Principal == null || addItem.Principal.AWS == null || addItem.Principal.AWS.Count == 0) { addItem.Principal = new Principal() { AWS = new List <string>() { "*" } }; } } if (oldStatements == null || oldStatements.Count == 0) { //没有Policy数据的情况,新建,修改或删除 foreach (var addItem in statements) { //跳过删除 if (addItem.IsDelete) { continue; } tempStatements.Add(addItem); } } else { foreach (var addItem in addStatements) { foreach (var oldItem in oldStatements) { //判断已经存在的条目是否包含现有要添加的条目 //如果存在条目,则更新;不存在条目,添加进去 if ((IsRootResource(bucketName, oldItem.Resource[0]) && IsRootResource(bucketName, addItem.Resource[0])) || oldItem.Resource[0].Equals(addItem.Resource[0], StringComparison.OrdinalIgnoreCase) ) { oldItem.IsDelete = true; //就记录标识为删除,不重新添加到待添加列表中 } } if (!addItem.IsDelete) { tempStatements.Add(addItem); } } foreach (var oldItem in oldStatements) { if (!oldItem.IsDelete) { tempStatements.Add(oldItem); } } } //reset info info.Version = _defaultPolicyVersion; info.Statement = tempStatements; string policyJson = JsonUtil.SerializeObject(info); await _client.SetPolicyAsync(new SetPolicyArgs() .WithBucket(bucketName) .WithPolicy(policyJson)); return(true); }