* update authz to exclude entire group if user does not have access to rule
* change rule update authz to not return changes because if user does not have access to any rule in group, they do not have access to the rule
* a new query that returns alerts in group by UID of alert that belongs to that group
* collect all affected groups during calculate changes
* update authorize to check access to groups
* update tests for calculateChanges to assert new fields
* add authorization tests
srv.log.Warn("query returned rules that belong to folder the user does not have access to. All rules that belong to that namespace will not be added to the response","folder_uid",groupKey.NamespaceUID)
returnErrResp(http.StatusUnauthorized,fmt.Errorf("%w to access the group because it does not have access to one or many data sources one or many rules in the group use",ErrAuthorization),"")
logger.Info("no authorized changes detected in the request. Do nothing","not_authorized_add",len(groupChanges.New),"not_authorized_update",len(groupChanges.Update),"not_authorized_delete",len(groupChanges.Delete))
logger.Info("user is not authorized to delete one or many rules in the group. those rules will be skipped","expected",len(groupChanges.Delete),"authorized",len(authorizedChanges.Delete))
logger.Info("provenance is not 'none' for one or many rules in the group that should be updated. those rules will be skipped",
"expected",len(authorizedChanges.Update),
"allowed",len(authorizedChanges.Update))
"expected",len(groupChanges.Update),
"allowed",len(groupChanges.Update))
}
logger.Debug("updating database with the authorized changes","add",len(finalChanges.New),"update",len(finalChanges.New),"delete",len(finalChanges.Delete))
// calculateChanges calculates the difference between rules in the group in the database and the submitted rules. If a submitted rule has UID it tries to find it in the database (in other groups).
// returns a list of rules that need to be added, updated and deleted. Deleted considered rules in the database that belong to the group but do not exist in the list of submitted rules.
ifok{// not ok can be when user creates a new rule group or moves existing alerts to a new group
if!authorizeAccessToRuleGroup(rules,evaluator){// if user is not authorized to do operation in the group that is being changed
returnfmt.Errorf("%w to change group %s because it does not have access to one or many rules in this group",ErrAuthorization,change.GroupKey.RuleGroup)
}
}elseiflen(change.Delete)>0{
// add a safeguard in the case of inconsistency. If user hit this then there is a bug in the calculating of changes struct
returnfmt.Errorf("failed to authorize changes in rule group %s. Detected %d deletes but group was not provided",change.GroupKey.RuleGroup,len(change.Delete))
returnfmt.Errorf("%w to delete an alert rule '%s' because the user does not have read permissions for one or many datasources the rule uses",ErrAuthorization,rule.UID)
returnnil,fmt.Errorf("%w to create a new alert rule '%s' because the user does not have read permissions for one or many datasources the rule uses",ErrAuthorization,rule.Title)
returnfmt.Errorf("%w to create a new alert rule '%s' because the user does not have read permissions for one or many datasources the rule uses",ErrAuthorization,rule.Title)
returnnil,fmt.Errorf("%w to update alert rule '%s' (UID: %s) because the user does not have read permissions for one or many datasources the rule uses",ErrAuthorization,rule.Existing.Title,rule.Existing.UID)
returnfmt.Errorf("%w to update alert rule '%s' (UID: %s) because the user does not have read permissions for one or many datasources the rule uses",ErrAuthorization,rule.Existing.Title,rule.Existing.UID)
}
// Check if the rule is moved from one folder to the current. If yes, then the user must have the authorization to delete rules from the source folder and add rules to the target folder.
// add a safeguard in the case of inconsistency. If user hit this then there is a bug in the calculating of changes struct
returnfmt.Errorf("failed to authorize moving an alert rule %s between groups because unable to check access to group %s from which the rule is moved",rule.Existing.UID,rule.Existing.RuleGroup)
}
if!authorizeAccessToRuleGroup(rules,evaluator){
returnfmt.Errorf("%w to move rule %s between two different groups because user does not have access to the source group %s",ErrAuthorization,rule.Existing.UID,rule.Existing.RuleGroup)
// GetAlertRulesGroupByRuleUID is a handler for retrieving a group of alert rules from that database by UID and organisation ID of one of rules that belong to that group.