seekia/internal/moderation/myReviews/myReviews.go

828 lines
28 KiB
Go
Raw Normal View History

// myReviews provides functions to retrieve a user's moderator reviews
// This package retrieves our reviews from the database.
// myBroadcasts keeps a backup of a moderator's reviews that is retained if the database is deleted.
package myReviews
import "seekia/internal/badgerDatabase"
import "seekia/internal/contentMetadata"
import "seekia/internal/encoding"
import "seekia/internal/helpers"
import "seekia/internal/identity"
import "seekia/internal/moderation/createReviews"
import "seekia/internal/moderation/readReviews"
import "seekia/internal/myIdentity"
import "seekia/internal/network/myBroadcasts"
import "seekia/internal/profiles/profileStorage"
import "seekia/internal/profiles/readProfiles"
import "slices"
import "bytes"
import "sync"
import "errors"
// This function will create and broadcast a new moderator review
//Outputs:
// -bool: My moderator identity exists
// -error
func CreateAndBroadcastMyReview(reviewMap map[string]string)(bool, error){
exists, myIdentityPublicKey, myIdentityPrivateKey, err := myIdentity.GetMyPublicPrivateIdentityKeys("Moderator")
if (err != nil) { return false, err }
if (exists == false){
return false, nil
}
newReview, err := createReviews.CreateReview(myIdentityPublicKey, myIdentityPrivateKey, reviewMap)
if (err != nil) { return false, err }
err = myBroadcasts.BroadcastMyReview(newReview)
if (err != nil) { return false, err }
ableToRead, _, _, _, _, newReviewType, _, _, _, err := readReviews.ReadReview(false, newReview)
if (err != nil) { return false, err }
if (ableToRead == false){
return false, errors.New("CreateReview is returning an invalid review.")
}
err = DeleteMyReviewsListCache(newReviewType)
if (err != nil) { return false, err }
return true, nil
}
// This function will return what a user's current verdict is for an identity
//Outputs:
// -bool: My Moderator Identity exists
// -bool: I have banned the identity
// -error
func GetMyNewestIdentityModerationVerdict(identityHash [16]byte, networkType byte)(bool, bool, error){
isValid := helpers.VerifyNetworkType(networkType)
if (isValid == false){
networkTypeString := helpers.ConvertByteToString(networkType)
return false, false, errors.New("GetMyNewestIdentityModerationVerdict called with invalid networkType: " + networkTypeString)
}
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, false, err }
if (myIdentityExists == false){
return false, false, nil
}
isValid, err = identity.VerifyIdentityHash(identityHash, false, "")
if (err != nil) { return false, false, err }
if (isValid == false){
identityHashHex := encoding.EncodeBytesToHexString(identityHash[:])
return false, false, errors.New("GetMyNewestIdentityModerationVerdict called with invalid identityHash: " + identityHashHex)
}
myReviewsList, err := getMyReviewsList(myIdentityHash, "Identity")
if (err != nil) { return false, false, err }
if (len(myReviewsList) == 0){
// Moderator has no reviews yet
return true, false, nil
}
reviewExists, _, _, err := readReviews.GetModeratorNewestIdentityReviewFromReviewsList(myReviewsList, myIdentityHash, identityHash, networkType)
if (err != nil){ return false, false, err }
if (reviewExists == true){
// Review must be a ban review, because Identities can only be banned
return true, true, nil
}
return true, false, nil
}
// This function will return what a user's current verdict is for a profile
// This will optionally check for profile attribute bans which would undo a full profile approval
// It will not check if we have banned the author identity
//Outputs:
// -bool: My Moderator identity exists
// -bool: Profile is disabled
// -bool: Profile metadata exists (needed to determine verdict)
// -bool: I have reviewed the profile (review exists and is not None)
// -string: Verdict ("Ban"/"Approve")
// -error
func GetMyNewestProfileModerationVerdict(profileHash [28]byte, integrateAttributeBans bool)(bool, bool, bool, bool, string, error){
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, false, false, false, "", err }
if (myIdentityExists == false){
return false, false, false, false, "", nil
}
_, profileIsDisabled, err := readProfiles.ReadProfileHashMetadata(profileHash)
if (err != nil){
profileHashHex := encoding.EncodeBytesToHexString(profileHash[:])
return false, false, false, false, "", errors.New("GetMyNewestProfileModerationVerdict called with invalid profile hash: " + profileHashHex)
}
metadataExists, _, profileNetworkType, _, _, profileIsDisabledB, _, attributeHashesMap, err := contentMetadata.GetProfileMetadata(profileHash)
if (err != nil) { return false, false, false, false, "", err }
if (metadataExists == false){
return true, profileIsDisabled, false, false, "", nil
}
if (profileIsDisabled != profileIsDisabledB){
return false, false, false, false, "", errors.New("GetProfileMetadata returning different profileIsDisabled status than ReadProfileHashMetadata.")
}
if (profileIsDisabled == true){
// Profile is disabled. It cannot be reviewed.
return true, true, true, false, "", nil
}
myProfileReviewsList, err := getMyReviewsList(myIdentityHash, "Profile")
if (err != nil) { return false, false, false, false, "", err }
fullProfileReviewExists, _, _, fullProfileVerdict, fullProfileVerdictTime, err := readReviews.GetModeratorNewestProfileReviewFromReviewsList(myProfileReviewsList, myIdentityHash, profileHash, profileNetworkType)
if (err != nil){ return false, false, false, false, "", err }
if (integrateAttributeBans == false){
if (fullProfileReviewExists == true){
return true, false, true, true, fullProfileVerdict, nil
}
return true, false, true, false, "", nil
}
if (fullProfileReviewExists == true && fullProfileVerdict == "Ban"){
// We do not have to check if we have banned any profile attributes, because we have already banned the full profile
return true, false, true, true, "Ban", nil
}
// Now we see if we have banned any attributes belonging to this profile
for _, attributeHash := range attributeHashesMap{
myIdentityExists, attributeMetadataExists, reviewExists, myVerdict, myVerdictTime, err := GetMyNewestProfileAttributeModerationVerdict(attributeHash, false)
if (err != nil) { return false, false, false, false, "", err }
if (myIdentityExists == false){
return false, false, false, false, "", errors.New("My identity not found after being found already.")
}
if (attributeMetadataExists == false){
// We don't have knowledge of profiles belonging to this profile in the attributeProfileHashesList entry in the database
// This should not happen unless those entries were deleted
// We will interpret this the same as no other profiles existing which contain this attribute
continue
}
if (reviewExists == true && myVerdict == "Ban"){
if (fullProfileReviewExists == true && myVerdictTime < fullProfileVerdictTime){
// We have approved the full profile after we banned this attribute
continue
}
// We have banned a profile attribute, thus, we have banned the profile.
return true, false, true, true, "Ban", nil
}
}
if (fullProfileReviewExists == true){
// We could not find any attribute bans that undo the full profile approval
return true, false, true, true, "Approve", nil
}
return true, false, true, false, "", nil
}
// This function will return a user's newest profile attribute verdict
// It will optionally check for full profile approvals, which it considers the same as approving all of the profile's attributes
//Outputs:
// -bool: My Moderator identity exists
// -bool: Attribute metadata exists (this is needed to determine verdict)
// -bool: I have reviewed the attribute (review exists and is not None)
// -string: Verdict ("Ban"/"Approve")
// -int64: Time of verdict
// -error
func GetMyNewestProfileAttributeModerationVerdict(attributeHash [27]byte, integrateFullProfileApprovals bool)(bool, bool, bool, string, int64, error){
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, false, false, "", 0, err }
if (myIdentityExists == false){
return false, false, false, "", 0, nil
}
isValid, err := readProfiles.VerifyAttributeHash(attributeHash, false, "", false, false)
if (err != nil) { return false, false, false, "", 0, err }
if (isValid == false){
attributeHashHex := encoding.EncodeBytesToHexString(attributeHash[:])
return false, false, false, "", 0, errors.New("GetMyNewestProfileAttributeModerationVerdict called with invalid attributeHash: " + attributeHashHex)
}
attributeMetadataExists, _, _, attributeNetworkType, attributeProfileHashesList, err := profileStorage.GetProfileAttributeMetadata(attributeHash)
if (err != nil) { return false, false, false, "", 0, err }
if (attributeMetadataExists == false){
// We cannot determine verdict.
return true, false, false, "", 0, nil
}
myAttributeReviewsList, err := getMyReviewsList(myIdentityHash, "Attribute")
if (err != nil) { return false, false, false, "", 0, err }
attributeReviewExists, _, _, attributeReviewVerdict, attributeReviewTime, err := readReviews.GetModeratorNewestProfileAttributeReviewFromReviewsList(myAttributeReviewsList, myIdentityHash, attributeHash, attributeNetworkType)
if (err != nil){ return false, false, false, "", 0, err }
if (integrateFullProfileApprovals == false){
if (attributeReviewExists == false){
return true, true, false, "", 0, nil
}
return true, true, true, attributeReviewVerdict, attributeReviewTime, nil
}
if (attributeReviewExists == true && attributeReviewVerdict == "Approve"){
// We approved the attribute
// We don't have to check for full profile approvals, because they would not change this verdict
return true, true, true, "Approve", attributeReviewTime, nil
}
// Now we check for full profile approvals
// A full profile approval is equivalent to an attribute approval for all attributes within the profile
// attributeProfileHashesList is a list of all profile hashes for profiles which contain the attribute
myProfileReviewsList, err := getMyReviewsList(myIdentityHash, "Profile")
if (err != nil) { return false, false, false, "", 0, err }
for _, profileHash := range attributeProfileHashesList{
// We are only checking for full profile approvals
// We don't need to check for profile attribute bans, because we are only concerned with the provided attribute's status
// A full profile approval approves all attributes.
// If we ban a full profile, it does not change the status of any of our attribute approvals of the profile
fullProfileReviewExists, _, _, fullProfileVerdict, fullProfileVerdictTime, err := readReviews.GetModeratorNewestProfileReviewFromReviewsList(myProfileReviewsList, myIdentityHash, profileHash, attributeNetworkType)
if (err != nil){ return false, false, false, "", 0, err }
if (fullProfileReviewExists == true && fullProfileVerdict == "Approve"){
if (attributeReviewExists == true && fullProfileVerdictTime < attributeReviewTime){
// We banned the attribute after approving the full profile
// The attribute ban is therefore disregarded.
continue
}
// We have approved the full profile after banning the attribute, thus, the attribute is approved
return true, true, true, "Approve", fullProfileVerdictTime, nil
}
}
if (attributeReviewExists == true){
// We could not find any full profile approvals that undo the attribute ban
return true, true, true, "Ban", attributeReviewTime, nil
}
return true, true, false, "", 0, nil
}
// This function will return what a user's current verdict is for a message
// -bool: My Moderator Identity exists
// -bool: Message metadata exists (this is needed to determine our verdict)
// -bool: I have reviewed the message (review exists and is not None)
// -string: Verdict ("Ban"/"Approve")
// -error
func GetMyNewestMessageModerationVerdict(messageHash [26]byte)(bool, bool, bool, string, error){
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, false, false, "", err }
if (myIdentityExists == false){
return false, false, false, "", nil
}
messageMetadataExists, _, messageNetworkType, _, _, messageCipherKeyHash, err := contentMetadata.GetMessageMetadata(messageHash)
if (err != nil){ return false, false, false, "", err }
if (messageMetadataExists == false){
// We cannot determine our verdict without message metadata
return true, false, false, "", nil
}
myReviewsList, err := getMyReviewsList(myIdentityHash, "Message")
if (err != nil) { return false, false, false, "", err }
if (len(myReviewsList) == 0){
// Moderator has no reviews yet
return true, true, false, "", nil
}
reviewExists, _, _, reviewVerdict, err := readReviews.GetModeratorNewestMessageReviewFromReviewsList(myReviewsList, myIdentityHash, messageHash, messageNetworkType, messageCipherKeyHash)
if (err != nil){ return false, false, false, "", err }
if (reviewExists == false){
return true, true, false, "", nil
}
return true, true, true, reviewVerdict, nil
}
// This function returns a list of all the identity hashes that the user has banned
//Outputs:
// -bool: My Moderator identity exists
// -[][16]byte: List of identity hashes user has banned
// -error
func GetMyBannedIdentityHashesList(networkType byte)(bool, [][16]byte, error){
isValid := helpers.VerifyNetworkType(networkType)
if (isValid == false){
networkTypeString := helpers.ConvertByteToString(networkType)
return false, nil, errors.New("GetMyBannedIdentityHashesList called with invalid networkType: " + networkTypeString)
}
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, nil
}
myIdentityReviewsMap, err := getMyNewestReviewsMap(myIdentityHash, "Identity", networkType)
if (err != nil) { return false, nil, err }
bannedIdentityHashesList := make([][16]byte, 0, len(myIdentityReviewsMap))
for reviewedIdentityHashString, _ := range myIdentityReviewsMap{
reviewedIdentityHashBytes := []byte(reviewedIdentityHashString)
if (len(reviewedIdentityHashBytes) != 16){
reviewedIdentityHashHex := encoding.EncodeBytesToHexString(reviewedIdentityHashBytes)
return false, nil, errors.New("getMyNewestReviewsMap returning invalid reviewedIdentityHash: " + reviewedIdentityHashHex)
}
reviewedIdentityHash := [16]byte(reviewedIdentityHashBytes)
bannedIdentityHashesList = append(bannedIdentityHashesList, reviewedIdentityHash)
}
return true, bannedIdentityHashesList, nil
}
//Outputs:
// -bool: My Moderator identity exists
// -map[[28]byte]string: Map of profile hashes user has reviewed (Profile hash -> "Approve"/"Ban")
// -error
func GetMyReviewedProfileHashesMap(profileType string, networkType byte)(bool, map[[28]byte]string, error){
if (profileType != "Mate" && profileType != "Host" && profileType != "Moderator"){
return false, nil, errors.New("GetMyReviewedProfileHashesMap called with invalid profile type: " + profileType)
}
isValid := helpers.VerifyNetworkType(networkType)
if (isValid == false){
networkTypeString := helpers.ConvertByteToString(networkType)
return false, nil, errors.New("GetMyReviewedProfileHashesMap called with invalid networkType: " + networkTypeString)
}
myIdentityExists, _, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, nil
}
allProfileHashesList, err := badgerDatabase.GetAllProfileHashes(profileType)
if (err != nil) { return false, nil, err }
//Map structure: Profile hash -> My Verdict
myReviewedProfileHashesMap := make(map[[28]byte]string)
for _, profileHash := range allProfileHashesList{
myIdentityExists, profileIsDisabled, profileMetadataExists, iHaveReviewed, myVerdict, err := GetMyNewestProfileModerationVerdict(profileHash, true)
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, errors.New("My identity not found after being found already.")
}
if (profileIsDisabled == true){
continue
}
if (profileMetadataExists == false){
continue
}
if (iHaveReviewed == true){
myReviewedProfileHashesMap[profileHash] = myVerdict
}
}
return true, myReviewedProfileHashesMap, nil
}
//Outputs:
// -bool: My Moderator identity exists
// -map[[27]byte]string: Map Structure: Attribute Hash -> Verdict
// -Map of profile attribute hashes user has reviewed (approved or banned)
// -error
func GetMyReviewedProfileAttributeHashesMap(networkType byte)(bool, map[[27]byte]string, error){
isValid := helpers.VerifyNetworkType(networkType)
if (isValid == false){
networkTypeString := helpers.ConvertByteToString(networkType)
return false, nil, errors.New("GetMyReviewedProfileAttributeHashesMap called with invalid networkType: " + networkTypeString)
}
myIdentityExists, _, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, nil
}
allProfileAttributeHashesList, err := badgerDatabase.GetAllReviewedProfileAttributeHashes()
if (err != nil) { return false, nil, err }
//Map structure: Attribute hash -> My verdict
myAttributeVerdictsMap := make(map[[27]byte]string)
for _, attributeHash := range allProfileAttributeHashesList{
myIdentityExists, attributeMetadataExists, myReviewExists, myVerdict, _, err := GetMyNewestProfileAttributeModerationVerdict(attributeHash, true)
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, errors.New("My moderator identity not found after being found already.")
}
if (attributeMetadataExists == false){
// We cannot determine our verdict for this attribute
continue
}
if (myReviewExists == true){
myAttributeVerdictsMap[attributeHash] = myVerdict
}
}
return true, myAttributeVerdictsMap, nil
}
//Outputs:
// -bool: My Moderator identity exists
// -[][26]byte: List of message hashes user has reviewed (approved or banned)
// -error
func GetMyReviewedMessageHashesList(networkType byte)(bool, [][26]byte, error){
isValid := helpers.VerifyNetworkType(networkType)
if (isValid == false){
networkTypeString := helpers.ConvertByteToString(networkType)
return false, nil, errors.New("GetMyReviewedMessageHashesList called with invalid networkType: " + networkTypeString)
}
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, nil
}
myMessageReviewsMap, err := getMyNewestReviewsMap(myIdentityHash, "Message", networkType)
if (err != nil) { return false, nil, err }
myReviewedMessageHashesList := make([][26]byte, 0, len(myMessageReviewsMap))
for messageHashString, reviewBytes := range myMessageReviewsMap{
messageHashBytes := []byte(messageHashString)
if (len(messageHashBytes) != 26){
messageHashHex := encoding.EncodeBytesToHexString(messageHashBytes)
return false, nil, errors.New("getMyNewestReviewsMap returning reviewsMap with invalid messageHash map key: " + messageHashHex)
}
messageHashArray := [26]byte(messageHashBytes)
ableToRead, _, reviewNetworkType, reviewerIdentityHash, _, reviewType, reviewedHash, _, _, err := readReviews.ReadReview(false, reviewBytes)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
return false, nil, errors.New("getMyNewestReviewsMap returning invalid review.")
}
if (reviewNetworkType != networkType){
return false, nil, errors.New("getMyNewestReviewsMap returning review of different networkType.")
}
if (reviewerIdentityHash != myIdentityHash){
return false, nil, errors.New("getMyNewestReviewsMap list contains review by different reviewer")
}
if (reviewType != "Message"){
return false, nil, errors.New("getMyNewestReviewsMap returns different reviewType review: " + reviewType)
}
areEqual := bytes.Equal(reviewedHash, messageHashBytes)
if (areEqual == false){
return false, nil, errors.New("getMyNewestReviewsMap returns key with different review reviewedHash")
}
myReviewedMessageHashesList = append(myReviewedMessageHashesList, messageHashArray)
}
return true, myReviewedMessageHashesList, nil
}
//Outputs:
// -bool: User moderator identity found
// -[][]byte: List of all reviews created by user, sorted from newest to oldest (Reviews with None verdict not included)
// -error
func GetMyNewestReviewsListSorted(reviewType string, networkType byte)(bool, [][]byte, error){
if (reviewType != "Identity" && reviewType != "Profile" && reviewType != "Attribute" && reviewType != "Message"){
return false, nil, errors.New("GetMyNewestReviewsListSorted called with invalid reviewType: " + reviewType)
}
isValid := helpers.VerifyNetworkType(networkType)
if (isValid == false){
networkTypeString := helpers.ConvertByteToString(networkType)
return false, nil, errors.New("GetMyNewestReviewsListSorted called with invalid networkType: " + networkTypeString)
}
myIdentityExists, myIdentityHash, err := myIdentity.GetMyIdentityHash("Moderator")
if (err != nil) { return false, nil, err }
if (myIdentityExists == false){
return false, nil, nil
}
myNewestReviewsMap, err := getMyNewestReviewsMap(myIdentityHash, reviewType, networkType)
if (err != nil) { return false, nil, err }
type ReviewObject struct{
ReviewBroadcastTime int64
ReviewBytes []byte
}
newestReviewObjectsList := make([]ReviewObject, 0, len(myNewestReviewsMap))
for reviewedHashString, reviewBytes := range myNewestReviewsMap{
reviewedHashBytes := []byte(reviewedHashString)
ableToRead, _, reviewNetworkType, reviewAuthorIdentityHash, reviewBroadcastTime, currentReviewType, currentReviewedHash, _, _, err := readReviews.ReadReview(false, reviewBytes)
if (err != nil) { return false, nil, err }
if (ableToRead == false){
return false, nil, errors.New("getMyNewestReviewsMap returning invalid review")
}
if (reviewNetworkType != networkType){
return false, nil, errors.New("getMyNewestReviewsMap returning review for different networkType.")
}
if (reviewAuthorIdentityHash != myIdentityHash){
return false, nil, errors.New("getMyNewestReviewsMap returning review by different author.")
}
if (currentReviewType != reviewType){
return false, nil, errors.New("getMyNewestReviewsMap returning review of a different reviewType.")
}
areEqual := bytes.Equal(reviewedHashBytes, currentReviewedHash)
if (areEqual == false){
return false, nil, errors.New("getMyNewestReviewsMap returning map where reviewedHash key does not match reviewBytes's.")
}
reviewObject := ReviewObject{
ReviewBroadcastTime: reviewBroadcastTime,
ReviewBytes: reviewBytes,
}
newestReviewObjectsList = append(newestReviewObjectsList, reviewObject)
}
compareReviewsFunction := func(reviewA ReviewObject, reviewB ReviewObject)int{
reviewABroadcastTime := reviewA.ReviewBroadcastTime
reviewBBroadcastTime := reviewB.ReviewBroadcastTime
if (reviewABroadcastTime == reviewBBroadcastTime){
return 0
}
if (reviewABroadcastTime < reviewBBroadcastTime){
return 1
}
return -1
}
slices.SortFunc(newestReviewObjectsList, compareReviewsFunction)
newestReviewsList := make([][]byte, 0, len(newestReviewObjectsList))
for _, reviewObject := range newestReviewObjectsList{
reviewBytes := reviewObject.ReviewBytes
newestReviewsList = append(newestReviewsList, reviewBytes)
}
return true, newestReviewsList, nil
}
//Outputs:
// -map[string]string: Reviewed Hash -> Newest Review Bytes
// -error
func getMyNewestReviewsMap(myIdentityHash [16]byte, reviewType string, networkType byte)(map[string][]byte, error){
if (reviewType != "Identity" && reviewType != "Profile" && reviewType != "Attribute" && reviewType != "Message"){
return nil, errors.New("getMyNewestReviewsMap called with invalid reviewType: " + reviewType)
}
reviewsList, err := getMyReviewsList(myIdentityHash, reviewType)
if (err != nil) { return nil, err }
newestReviewsMap, err := readReviews.GetNewestModeratorReviewsMapFromReviewsList(reviewsList, myIdentityHash, networkType, true, reviewType)
if (err != nil) { return nil, err }
return newestReviewsMap, nil
}
// We read our reviews into memory so we don't have to retrieve them from the database each time
var myIdentityReviewsList []readReviews.ReviewWithHash
var myIdentityReviewsListMutex sync.RWMutex
var myProfileReviewsList []readReviews.ReviewWithHash
var myProfileReviewsListMutex sync.RWMutex
var myAttributeReviewsList []readReviews.ReviewWithHash
var myAttributeReviewsListMutex sync.RWMutex
var myMessageReviewsList []readReviews.ReviewWithHash
var myMessageReviewsListMutex sync.RWMutex
// We call this function whenever we add a new review to the database
func DeleteMyReviewsListCache(reviewType string)error{
if (reviewType == "Identity"){
myIdentityReviewsListMutex.Lock()
myIdentityReviewsList = nil
myIdentityReviewsListMutex.Unlock()
return nil
} else if (reviewType == "Profile"){
myProfileReviewsListMutex.Lock()
myProfileReviewsList = nil
myProfileReviewsListMutex.Unlock()
return nil
} else if (reviewType == "Attribute"){
myAttributeReviewsListMutex.Lock()
myAttributeReviewsList = nil
myAttributeReviewsListMutex.Unlock()
return nil
} else if (reviewType == "Message"){
myMessageReviewsListMutex.Lock()
myMessageReviewsList = nil
myMessageReviewsListMutex.Unlock()
return nil
}
return errors.New("DeleteMyReviewsListCache called with invalid reviewType: " + reviewType)
}
// This function returns our reviews for all networkTypes.
// It does not copy each review object's review bytes, so returned review bytes should never be edited
func getMyReviewsList(myIdentityHash [16]byte, reviewType string)([]readReviews.ReviewWithHash, error){
// We first attempt to return the list stored in memory
if (reviewType == "Identity"){
myIdentityReviewsListMutex.RLock()
if (myIdentityReviewsList != nil){
listCopy := slices.Clone(myIdentityReviewsList)
myIdentityReviewsListMutex.RUnlock()
return listCopy, nil
}
myIdentityReviewsListMutex.RUnlock()
} else if (reviewType == "Profile"){
myProfileReviewsListMutex.RLock()
if (myProfileReviewsList != nil){
listCopy := slices.Clone(myProfileReviewsList)
myProfileReviewsListMutex.RUnlock()
return listCopy, nil
}
myProfileReviewsListMutex.RUnlock()
} else if (reviewType == "Attribute"){
myAttributeReviewsListMutex.RLock()
if (myAttributeReviewsList != nil){
listCopy := slices.Clone(myAttributeReviewsList)
myAttributeReviewsListMutex.RUnlock()
return listCopy, nil
}
myAttributeReviewsListMutex.RUnlock()
} else if (reviewType == "Message"){
myMessageReviewsListMutex.RLock()
if (myMessageReviewsList != nil){
listCopy := slices.Clone(myMessageReviewsList)
myMessageReviewsListMutex.RUnlock()
return listCopy, nil
}
myMessageReviewsListMutex.RUnlock()
} else {
return nil, errors.New("getMyReviewsList called with invalid reviewType: " + reviewType)
}
// The list does not exist in memory
// We will create a new list
exists, myReviewHashesList, err := badgerDatabase.GetReviewerReviewHashesList(myIdentityHash, reviewType)
if (err != nil) { return nil, err }
if (exists == false){
emptyList := make([]readReviews.ReviewWithHash, 0)
return emptyList, nil
}
newReviewsList := make([]readReviews.ReviewWithHash, 0)
for _, reviewHash := range myReviewHashesList{
exists, reviewBytes, err := badgerDatabase.GetReview(reviewHash)
if (err != nil) { return nil, err }
if (exists == false) {
// Reviewer reviews list is outdated, will be updated automatically
continue
}
reviewObject := readReviews.ReviewWithHash{
ReviewHash: reviewHash,
ReviewBytes: reviewBytes,
}
newReviewsList = append(newReviewsList, reviewObject)
}
if (reviewType == "Identity"){
myIdentityReviewsListMutex.Lock()
myIdentityReviewsList = newReviewsList
listCopy := slices.Clone(myIdentityReviewsList)
myIdentityReviewsListMutex.Unlock()
return listCopy, nil
} else if (reviewType == "Profile"){
myProfileReviewsListMutex.Lock()
myProfileReviewsList = newReviewsList
listCopy := slices.Clone(myProfileReviewsList)
myProfileReviewsListMutex.Unlock()
return listCopy, nil
} else if (reviewType == "Attribute"){
myAttributeReviewsListMutex.Lock()
myAttributeReviewsList = newReviewsList
listCopy := slices.Clone(myAttributeReviewsList)
myAttributeReviewsListMutex.Unlock()
return listCopy, nil
}
// reviewType == "Message"){
myMessageReviewsListMutex.Lock()
myMessageReviewsList = newReviewsList
listCopy := slices.Clone(myMessageReviewsList)
myMessageReviewsListMutex.Unlock()
return listCopy, nil
}