Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e9dbb9e
feat: import privacy-pal
tianrendong Oct 7, 2023
511bd03
fix: missing firestoreSDK in go.sum
tianrendong Oct 7, 2023
b4cdb98
feat: privacy access request endpoint
tianrendong Oct 7, 2023
944a774
fix: privacy access route gets user from context
tianrendong Oct 7, 2023
5a6657f
feat: command to update privacy-pal version
tianrendong Oct 7, 2023
c4809ea
fix: show more info
tianrendong Oct 7, 2023
5a07c5c
feat: v0.2.1 working
tianrendong Oct 7, 2023
06e09d9
feat: updated privacy pal version
jennyyu212 Oct 10, 2023
54c9a34
fix: return JSON instead of string
jennyyu212 Oct 10, 2023
3e829b8
feat: updated privacy-pal package
jennyyu212 Oct 13, 2023
95ee938
use new pacakge
tianrendong Oct 20, 2023
0e69316
feat: handle access request with user, course, section data
tianrendong Nov 15, 2023
85f18e0
feat: complete data access
tianrendong Nov 25, 2023
b2120c0
fix: make command for update privacy pal
tianrendong Nov 25, 2023
676beeb
use privacy-pal v1.0.0
tianrendong Dec 13, 2023
0273fdb
handle deletion request
tianrendong Dec 14, 2023
b4e73e6
rename helpers for privacy pal handlers
tianrendong Dec 14, 2023
39a26cc
use privacy-pal v1.2.0 and update handleAccess
tianrendong Dec 14, 2023
efe11c1
fix handleDeleteSurvey results nil
tianrendong Dec 14, 2023
668ddb3
handle course deletion filter swap subcollection by studentID
tianrendong Dec 14, 2023
3e33e1f
use privacy pal 1.3.0
tianrendong Dec 15, 2023
ccabe23
fix filter on swap instead of survey for deletion
tianrendong Dec 15, 2023
17d37b1
errors.go to standardize privacy errors
tianrendong Dec 15, 2023
09b6be4
enable writeToDatabase and temp get for deletion
tianrendong Dec 15, 2023
eac8daa
Merge pull request #116 from privacy-pal/privacy-pal
tianrendong Dec 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
.PHONY: backend frontend
.PHONY: backend frontend update_privacy_pal

backend:
cd backend ; go run main.go

frontend:
cd frontend ; npm i && npm run dev
cd frontend ; npm i && npm run dev

update_privacy_pal:
cd backend ; go get github.com/privacy-pal/privacy-pal@latest
64 changes: 40 additions & 24 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,63 @@ module github.com/fullstackatbrown/here

go 1.18

require google.golang.org/api v0.103.0
require google.golang.org/api v0.147.0

require (
cloud.google.com/go/firestore v1.9.0
cloud.google.com/go/storage v1.28.0 // indirect
cloud.google.com/go/firestore v1.13.0
cloud.google.com/go/storage v1.33.0 // indirect
)

require (
firebase.google.com/go v3.13.0+incompatible
github.com/go-chi/chi/v5 v5.0.8
github.com/go-chi/render v1.0.2
github.com/google/go-cmp v0.5.9
github.com/google/go-cmp v0.6.0
github.com/mitchellh/mapstructure v1.5.0
github.com/privacy-pal/privacy-pal/go v1.3.0
github.com/rs/cors v1.8.3
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
google.golang.org/grpc v1.53.0
google.golang.org/grpc v1.58.3
)

require (
cloud.google.com/go v0.107.0 // indirect
cloud.google.com/go/compute v1.15.1 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
go.mongodb.org/mongo-driver v1.13.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
)

require (
cloud.google.com/go v0.110.8 // indirect
cloud.google.com/go/compute v1.23.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.8.0 // indirect
cloud.google.com/go/longrunning v0.3.0 // indirect
cloud.google.com/go/iam v1.1.3 // indirect
cloud.google.com/go/longrunning v0.5.2 // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/golang/glog v1.1.1
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.1
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/joho/godotenv v1.5.1
go.opencensus.io v0.24.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
google.golang.org/protobuf v1.28.1 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sync v0.4.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a // indirect
google.golang.org/protobuf v1.31.0 // indirect
)
159 changes: 110 additions & 49 deletions backend/go.sum

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion backend/pkg/models/auth.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package models

import "fmt"
import (
"fmt"
)

const (
FirestoreProfilesCollection = "user_profiles"
Expand Down
22 changes: 12 additions & 10 deletions backend/pkg/models/survey.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ const (
)

type Survey struct {
ID string `firestore:"id,omitempty"`
CourseID string `firestore:"courseID"`
Name string `firestore:"name"`
Description string `firestore:"description"`
Published bool `firestore:"published"`
EndTime string `firestore:"endTime"`
Options []*SurveyOption `firestore:"options"`
Responses map[string][]string `firestore:"responses"`
Results map[string][]CourseUserData `firestore:"results"`
ID string `firestore:"id,omitempty"`
CourseID string `firestore:"courseID"`
Name string `firestore:"name"`
Description string `firestore:"description"`
Published bool `firestore:"published"`
EndTime string `firestore:"endTime"`
Options []*SurveyOption `firestore:"options"`
// Map from userID to list of chosen options
Responses map[string][]string `firestore:"responses"`
// Map from option to list of student data
Results map[string][]CourseUserData `firestore:"results"`
// Map from the option to a map from sectionID to capacity
SectionCapacity map[string]map[string]int `firestore:"sectionCapacity,omitempty"`
SectionCapacity map[string]map[string]int `firestore:"sectionCapacity,omitempty"`
}

type SurveyOption struct {
Expand Down
35 changes: 35 additions & 0 deletions backend/pkg/privacy/assignment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package privacy

import (
"cloud.google.com/go/firestore"
pal "github.com/privacy-pal/privacy-pal/go/pkg"
)

func handleAccessAssignment(dataSubjectId string, currentDbObjLocator pal.Locator, dbObj pal.DatabaseObject) (data map[string]interface{}, err error) {
data = map[string]interface{}{
"name": dbObj["name"],
"optional": dbObj["optional"],
"maxScore": dbObj["maxScore"],
"releaseDate": dbObj["releaseDate"],
"dueDate": dbObj["dueDate"],
"grade": dbObj["grades"].(map[string]interface{})[dataSubjectId],
}

return
}

func handleDeleteAssignment(dataSubjectId string, currentDbObjLocator pal.Locator, dbObj pal.DatabaseObject) (nodesToTraverse []pal.Locator, deleteNode bool, fieldsToUpdate pal.FieldUpdates, err error) {
deleteNode = false

// remove grades[dataSubjectId] if exists
fieldsToUpdate = pal.FieldUpdates{
FirestoreUpdates: []firestore.Update{
{
Path: "grades." + dataSubjectId,
Value: firestore.Delete,
},
},
}

return
}
96 changes: 96 additions & 0 deletions backend/pkg/privacy/course.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package privacy

import (
"cloud.google.com/go/firestore"
"github.com/fullstackatbrown/here/pkg/models"
pal "github.com/privacy-pal/privacy-pal/go/pkg"
)

func handleAccessCourse(dataSubjectId string, currentDbObjLocator pal.Locator, dbObj pal.DatabaseObject) (data map[string]interface{}, err error) {
data = map[string]interface{}{
"title": dbObj["title"],
}

data["assignments"] = pal.Locator{
LocatorType: pal.Collection,
DataType: AssignmentDataType,
FirestoreLocator: pal.FirestoreLocator{
CollectionPath: []string{models.FirestoreCoursesCollection, models.FirestoreAssignmentsCollection},
DocIDs: []string{currentDbObjLocator.FirestoreLocator.DocIDs[0]},
},
}

data["surveys"] = pal.Locator{
LocatorType: pal.Collection,
DataType: SurveyDataType,
FirestoreLocator: pal.FirestoreLocator{
CollectionPath: []string{models.FirestoreCoursesCollection, models.FirestoreSurveysCollection},
DocIDs: []string{currentDbObjLocator.FirestoreLocator.DocIDs[0]},
},
}

data["swaps"] = pal.Locator{
LocatorType: pal.Collection,
DataType: SwapDataType,
FirestoreLocator: pal.FirestoreLocator{
CollectionPath: []string{models.FirestoreCoursesCollection, models.FirestoreSwapsCollection},
DocIDs: []string{currentDbObjLocator.FirestoreLocator.DocIDs[0]},
// Query for swaps where studentID is the dataSubjectID
Filters: []pal.Filter{
{
Path: "studentID",
Op: "==",
Value: dataSubjectId,
},
},
},
}

return
}

func handleDeleteCourse(dataSubjectId string, currentDbObjLocator pal.Locator, dbObj pal.DatabaseObject) (nodesToTraverse []pal.Locator, deleteNode bool, fieldsToUpdate pal.FieldUpdates, err error) {
deleteNode = false

updates := []firestore.Update{}
// remove student associated with dataSubjectId from the students field
updates = append(updates, firestore.Update{
Path: "students." + dataSubjectId,
Value: firestore.Delete,
})
// remove permission associated with dataSubjectId from the permissions field
updates = append(updates, firestore.Update{
Path: "permissions." + dataSubjectId,
Value: firestore.Delete,
})

// add swaps and surveys to nodesToTraverse
nodesToTraverse = append(nodesToTraverse, pal.Locator{
LocatorType: pal.Collection,
DataType: SwapDataType,
FirestoreLocator: pal.FirestoreLocator{
CollectionPath: []string{models.FirestoreCoursesCollection, models.FirestoreSwapsCollection},
DocIDs: []string{currentDbObjLocator.FirestoreLocator.DocIDs[0]},
Filters: []pal.Filter{
{
Path: "studentID",
Op: "==",
Value: dataSubjectId,
},
},
},
})
nodesToTraverse = append(nodesToTraverse, pal.Locator{
LocatorType: pal.Collection,
DataType: SurveyDataType,
FirestoreLocator: pal.FirestoreLocator{
CollectionPath: []string{models.FirestoreCoursesCollection, models.FirestoreSurveysCollection},
DocIDs: []string{currentDbObjLocator.FirestoreLocator.DocIDs[0]},
},
})

fieldsToUpdate = pal.FieldUpdates{
FirestoreUpdates: updates,
}
return
}
11 changes: 11 additions & 0 deletions backend/pkg/privacy/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package privacy

import "fmt"

var (
invalidLocatorDataType = fmt.Errorf("invalid locator data type")
)

func cannotCastFieldToType(field string, castType string) error {
return fmt.Errorf("cannot cast %s to %s", field, castType)
}
54 changes: 54 additions & 0 deletions backend/pkg/privacy/privacy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package privacy

import (
pal "github.com/privacy-pal/privacy-pal/go/pkg"
)

const (
UserDataType = "user"
CourseDataType = "course"
SectionDataType = "section"
AssignmentDataType = "assignment"
SurveyDataType = "survey"
SwapDataType = "swap"
)

func HandleAccess(dataSubjectId string, currentDbObjLocator pal.Locator, dbObj pal.DatabaseObject) (data map[string]interface{}, err error) {
switch currentDbObjLocator.DataType {
case UserDataType:
return handleAccessUser(dataSubjectId, currentDbObjLocator, dbObj)
case CourseDataType:
return handleAccessCourse(dataSubjectId, currentDbObjLocator, dbObj)
case SectionDataType:
return handleAccessSection(dataSubjectId, currentDbObjLocator, dbObj)
case AssignmentDataType:
return handleAccessAssignment(dataSubjectId, currentDbObjLocator, dbObj)
case SurveyDataType:
return handleAccessSurvey(dataSubjectId, currentDbObjLocator, dbObj)
case SwapDataType:
return handleAccessSwap(dataSubjectId, currentDbObjLocator, dbObj)
default:
err = invalidLocatorDataType
return
}
}

func HandleDelete(dataSubjectId string, currentDbObjLocator pal.Locator, dbObj pal.DatabaseObject) (nodesToTraverse []pal.Locator, deleteNode bool, fieldsToUpdate pal.FieldUpdates, err error) {
switch currentDbObjLocator.DataType {
case UserDataType:
return handleDeleteUser(dataSubjectId, currentDbObjLocator, dbObj)
case CourseDataType:
return handleDeleteCourse(dataSubjectId, currentDbObjLocator, dbObj)
case SectionDataType:
return handleDeleteSection(dataSubjectId, currentDbObjLocator, dbObj)
case AssignmentDataType:
return handleDeleteAssignment(dataSubjectId, currentDbObjLocator, dbObj)
case SurveyDataType:
return handleDeleteSurvey(dataSubjectId, currentDbObjLocator, dbObj)
case SwapDataType:
return handleDeleteSwap(dataSubjectId, currentDbObjLocator, dbObj)
default:
err = invalidLocatorDataType
return
}
}
Loading