Skip to content

Commit

Permalink
Made it possible for orgs to be creators, and admins inside the org t…
Browse files Browse the repository at this point in the history
…o modify them
  • Loading branch information
frikky committed Sep 26, 2023
1 parent beb4669 commit b970917
Show file tree
Hide file tree
Showing 5 changed files with 311 additions and 13 deletions.
103 changes: 102 additions & 1 deletion cloudSync.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package shuffle

import (
"bytes"
"net/url"
"context"
"encoding/json"
"errors"
Expand Down Expand Up @@ -214,6 +215,17 @@ func HandleAlgoliaAppSearchByUser(ctx context.Context, userId string) ([]Algolia
}

func HandleAlgoliaCreatorSearch(ctx context.Context, username string) (AlgoliaSearchCreator, error) {
tmpUsername, err := url.QueryUnescape(username)
if err == nil {
username = tmpUsername
}

if strings.HasPrefix(username, "@") {
username = strings.Replace(username, "@", "", 1)
}

username = strings.ToLower(strings.TrimSpace(username))

cacheKey := fmt.Sprintf("algolia_creator_%s", username)
searchCreator := AlgoliaSearchCreator{}
cache, err := GetCache(ctx, cacheKey)
Expand Down Expand Up @@ -316,7 +328,7 @@ func HandleAlgoliaCreatorSearch(ctx context.Context, username string) (AlgoliaSe
return foundUser, nil
}

func HandleAlgoliaCreatorUpload(ctx context.Context, user User, overwrite bool) (string, error) {
func HandleAlgoliaCreatorUpload(ctx context.Context, user User, overwrite bool, isOrg bool) (string, error) {
algoliaClient := os.Getenv("ALGOLIA_CLIENT")
algoliaSecret := os.Getenv("ALGOLIA_SECRET")
if len(algoliaClient) == 0 || len(algoliaSecret) == 0 {
Expand Down Expand Up @@ -359,6 +371,7 @@ func HandleAlgoliaCreatorUpload(ctx context.Context, user User, overwrite bool)
TimeEdited: timeNow,
Image: user.PublicProfile.GithubAvatar,
Username: user.PublicProfile.GithubUsername,
IsOrg: isOrg,
},
}

Expand All @@ -372,6 +385,52 @@ func HandleAlgoliaCreatorUpload(ctx context.Context, user User, overwrite bool)
return user.Id, nil
}

func HandleAlgoliaCreatorDeletion(ctx context.Context, userId string) (error) {
algoliaClient := os.Getenv("ALGOLIA_CLIENT")
algoliaSecret := os.Getenv("ALGOLIA_SECRET")
if len(algoliaClient) == 0 || len(algoliaSecret) == 0 {
log.Printf("[WARNING] ALGOLIA_CLIENT or ALGOLIA_SECRET not defined")
return errors.New("Algolia keys not defined")
}

algClient := search.NewClient(algoliaClient, algoliaSecret)
algoliaIndex := algClient.InitIndex("creators")
res, err := algoliaIndex.Search(userId)
if err != nil {
log.Printf("[WARNING] Failed searching Algolia creators: %s", err)
return err
}

var newRecords []AlgoliaSearchCreator
err = res.UnmarshalHits(&newRecords)
if err != nil {
log.Printf("[WARNING] Failed unmarshaling from Algolia creators: %s", err)
return err
}

//log.Printf("RECORDS: %d", len(newRecords))
foundItem := AlgoliaSearchCreator{}
for _, newRecord := range newRecords {
if newRecord.ObjectID == userId {
foundItem = newRecord
break
}
}

// Should delete it?
if len(foundItem.ObjectID) > 0 {
_, err = algoliaIndex.DeleteObject(foundItem.ObjectID)
if err != nil {
log.Printf("[WARNING] Algolia Creator delete problem: %s", err)
return err
}

log.Printf("[INFO] Successfully removed creator %s with ID %s FROM ALGOLIA!", foundItem.Username, userId)
}

return nil
}

// Shitty temorary system
// Adding schedule to run over with another algorithm
// as well as this one, as to increase priority based on popularity:
Expand Down Expand Up @@ -675,3 +734,45 @@ func RedirectUserRequest(w http.ResponseWriter, req *http.Request) {
DeleteCache(ctx, fmt.Sprintf("session_%s", c.Value))
}
}

// Checks if a specific user should have "self" access to a creator user
// A creator user can be both a user and an org, so this got a bit tricky
func CheckCreatorSelfPermission(ctx context.Context, requestUser, creatorUser User, algoliaUser *AlgoliaSearchCreator) bool {
if project.Environment != "cloud" {
return false
}

if creatorUser.Id == requestUser.Id {
return true
} else {
for _, user := range algoliaUser.Synonyms {
if user == requestUser.Id {
return true
}
}

if algoliaUser.IsOrg {
log.Printf("[AUDIT] User %s (%s) is an org. Checking if the current user should have access.", algoliaUser.Username, algoliaUser.ObjectID)
// Get the org and check
org, err := GetOrgByCreatorId(ctx, algoliaUser.ObjectID)
if err != nil {
log.Printf("[WARNING] Couldn't find org for creator %s (%s): %s", algoliaUser.Username, algoliaUser.ObjectID, err)
return false
}

log.Printf("[AUDIT] Found org %s (%s) for creator %s (%s)", org.Name, org.Id, algoliaUser.Username, algoliaUser.ObjectID)
for _, user := range org.Users {
if user.Id == requestUser.Id {
if user.Role == "admin" {
return true
}

break
}
}

}
}

return false
}
90 changes: 90 additions & 0 deletions db-connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -2606,6 +2606,96 @@ func GetAllWorkflows(ctx context.Context, orgId string) ([]Workflow, error) {
return allworkflows, nil
}

func GetOrgByCreatorId(ctx context.Context, id string) (*Org, error) {
nameKey := "Organizations"
cacheKey := fmt.Sprintf("creator_%s_%s", nameKey, id)

curOrg := &Org{}
if project.CacheDb {
cache, err := GetCache(ctx, cacheKey)
if err == nil {
cacheData := []byte(cache.([]uint8))
//log.Printf("CACHEDATA: %s", cacheData)
err = json.Unmarshal(cacheData, &curOrg)
if err == nil {
return curOrg, nil
}
} else {
//log.Printf("[DEBUG] Failed getting cache for org: %s", err)
}
}

setOrg := false
if project.DbType == "opensearch" {
} else {
query := datastore.NewQuery(nameKey).Filter("creator_id =", id).Limit(1)

allOrgs := []Org{}
_, err := project.Dbclient.GetAll(ctx, query, &allOrgs)
if err != nil {
return curOrg, err
}

if len(allOrgs) > 0 {
curOrg = &allOrgs[0]
}
}

// How does this happen?
if len(curOrg.Id) == 0 {
curOrg.Id = id
return curOrg, errors.New(fmt.Sprintf("Couldn't find creator org with ID %s", curOrg.Id))
}

newUsers := []User{}
for _, user := range curOrg.Users {
user.Password = ""
user.Session = ""
user.ResetReference = ""
user.PrivateApps = []WorkflowApp{}
user.VerificationToken = ""
//user.ApiKey = ""
user.Executions = ExecutionInfo{}
newUsers = append(newUsers, user)
}

curOrg.Users = newUsers
if len(curOrg.Tutorials) == 0 {
curOrg = GetTutorials(ctx, *curOrg, true)
}

// Making sure to skip old irrelevant priorities
newPriorities := []Priority{}
for _, priority := range curOrg.Priorities {
if priority.Type == "usecases" {
continue
}

newPriorities = append(newPriorities, priority)
}

curOrg.Priorities = newPriorities
if project.CacheDb {
neworg, err := json.Marshal(curOrg)
if err != nil {
log.Printf("[ERROR] Failed marshalling org for cache: %s", err)
return curOrg, nil
}

err = SetCache(ctx, cacheKey, neworg, 1440)
if err != nil {
log.Printf("[ERROR] Failed updating org cache: %s", err)
}

if setOrg {
log.Printf("[INFO] UPDATING ORG %s!!", curOrg.Id)
SetOrg(ctx, *curOrg, curOrg.Id)
}
}

return curOrg, nil
}

// ListBooks returns a list of books, ordered by title.
// Handles org grabbing and user / org migrations
func GetOrg(ctx context.Context, id string) (*Org, error) {
Expand Down
2 changes: 1 addition & 1 deletion oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ func HandleNewGithubRegister(resp http.ResponseWriter, request *http.Request) {
return
}

_, err = HandleAlgoliaCreatorUpload(ctx, user, false)
_, err = HandleAlgoliaCreatorUpload(ctx, user, false, false)
if err != nil {
log.Printf("[ERROR] Failed making user %s' information public")
}
Expand Down
Loading

0 comments on commit b970917

Please sign in to comment.