Skip to content

Conversation

@satti-hari-krishna-reddy
Copy link
Contributor

This PR fixes notification failures, like when an empty API key is sent to execute a notification workflow, causing it to fail. One of the potential issues is when an admin exists in the org but has no API key; autogenerating a key helps fix this.

The second fix is for a broken access control check. It was trying to see if a user was a member of the org, but it was mistakenly comparing a user's ID to itself, which (incorrectly) always passed the check.

Copy link
Member

@frikky frikky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks big, but these are small issues :)

The #1 point: Algorithm fix & Error alerting is more important than passing in users and hoping that fixes it.

notifications.go Outdated

// Extract authenticated user if provided
var requestingUser *User
if len(authenticatedUser) > 0 && authenticatedUser[0] != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should passing in this EVER be necessary?

I can understand it if notifications are supposed to be personal, but otherwise, this just makes no sense, as the requesting user themselves could be missing permissions and are now bypassing algorithmic scrutiny.

notifications.go Outdated
if err != nil {
log.Printf("[WARNING] Error getting parent org %s in createOrgNotification: %s. This is usually a region problem, and may cause issues with notification workflows..", orgId, err)
//return err
log.Printf("[WARNING] Error getting parent org %s in createOrgNotification: %s. Keeping authOrg as current org.", org.CreatorOrg, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why print so much? Our logs will get clogged

notifications.go Outdated

// Look for admin with API key
for _, user := range authOrg.Users {
if user.Role == "admin" && len(user.Id) > 0 && len(selectedApikey) == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't the entire problem here that we were only considering admins? Shouldn't it work for non-admins as well, as long as they have editor access?

notifications.go Outdated
if err == nil && len(foundUser.ApiKey) > 0 {
selectedApikey = foundUser.ApiKey
break
if err == nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To help with indents AKA readability, write opposite logic instead:

if err != nil {
  continue
}

notifications.go Outdated
if err == nil {
if len(foundUser.ApiKey) > 0 {
selectedApikey = foundUser.ApiKey
log.Printf("[DEBUG] Using admin's API key for notification workflow")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want verbose things you CAN see, but don't have to see, then wrap text in

if debug {
  log.Printf("[DEBUG] ....")
}

then we can turn it on or off :)

notifications.go Outdated
// If no admin key found, use requesting user's key
if len(selectedApikey) == 0 && requestingUser != nil && len(requestingUser.ApiKey) > 0 {
selectedApikey = requestingUser.ApiKey
log.Printf("[INFO] No admin API key available. Using requesting user's (%s) API key for notification workflow", requestingUser.Username)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an error condition when trying to run the workflow instead.

If we don't have a valid account in an org, something is VERY wrong, and we should literally get an alert called up about it. Not this flimsy fallback fallback which doesn't solve anything.

notifications.go Outdated

selectedApikey := ""
// Look for admin with API key
for _, user := range filteredUsers {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waait, why do we have two for loops for this

notifications.go Outdated
}

// If no admin key found, use requesting user's key
if len(selectedApikey) == 0 && requestingUser != nil && len(requestingUser.ApiKey) > 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this code again as well 🤔

notifications.go Outdated
return
}

if project.Environment == "cloud" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of this section?

Notifications are region specific, and since they aren't saved in the "Org" index, this will just send them to the void lol

notifications.go Outdated
notification.ReferenceUrl,
orgId,
false,
&user, // Pass authenticated user for API key fallback
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No pls. It does kind of make sense in this specific scenario, but doesn't help all the other 50 places we are calling the function

@frikky frikky merged commit f7a4f5e into Shuffle:main Nov 12, 2025
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants