diff --git a/apps/db-adapter/internal/api/authorization_by_id.go b/apps/db-adapter/internal/api/authorization_by_id.go index 55a3a2a..2766ee0 100644 --- a/apps/db-adapter/internal/api/authorization_by_id.go +++ b/apps/db-adapter/internal/api/authorization_by_id.go @@ -7,8 +7,39 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph" ) -func userWithIdHasAccessToGivenPerson(ctx context.Context, session neo4j.SessionWithContext, userId, personId int) bool { - _, err := session.ExecuteRead(ctx, memgraph.GetPersonById(ctx, userId)) - //TODO - return err == nil +type accessMode int + +const ( + accessModeNone accessMode = iota + accessModeRead + accessModeWrite +) + +func userWithIdHasAccessToGivenPerson(ctx context.Context, session neo4j.SessionWithContext, userId, personId int) accessMode { + resPerson, err := session.ExecuteRead(ctx, memgraph.GetPersonById(ctx, userId)) + if err != nil { + return accessModeNone + } + + resPersonMap, ok := resPerson.(map[string]any) + if !ok { + return accessModeNone + } + + if resPersonMap["id"] == userId { + return accessModeWrite + } + + AllowAdminAccess, ok := resPersonMap["allow_admin_access"].([]map[string]any) + if !ok { + return accessModeNone + } + + for _, admin := range AllowAdminAccess { + if admin["id"].(int) == userId { + return accessModeWrite + } + } + + return accessModeNone } diff --git a/apps/db-adapter/internal/api/person.go b/apps/db-adapter/internal/api/person.go index e5ee1c9..d4fc7d5 100644 --- a/apps/db-adapter/internal/api/person.go +++ b/apps/db-adapter/internal/api/person.go @@ -29,6 +29,7 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) { ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer cancel() session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + defer closeSession(c.Request.Context(), session, srv.dbOpTimeout) qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer qCancel() @@ -46,10 +47,11 @@ func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByI ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer cancel() session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + defer closeSession(c.Request.Context(), session, srv.dbOpTimeout) actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer acancel() - if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + if userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) == accessModeNone { c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) return @@ -71,10 +73,11 @@ func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDelet ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer cancel() session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + defer closeSession(c.Request.Context(), session, srv.dbOpTimeout) actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer acancel() - if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + if userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) != accessModeWrite { c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) return @@ -103,7 +106,9 @@ func (srv *server) UpdatePerson(c *gin.Context, id int, params api.UpdatePersonP actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer acancel() session := srv.db.NewSession(actx, neo4j.SessionConfig{}) - if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + defer closeSession(c.Request.Context(), session, srv.dbOpTimeout) + + if userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) != accessModeWrite { c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) return @@ -125,10 +130,11 @@ func (srv *server) HardDeletePerson(c *gin.Context, id int, params api.HardDelet ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer cancel() session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + defer closeSession(c.Request.Context(), session, srv.dbOpTimeout) actx, acancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer acancel() - if !userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) { + if userWithIdHasAccessToGivenPerson(actx, session, params.XUserID, id) != accessModeWrite { c.JSON(http.StatusUnauthorized, gin.H{"msg": "User does not have access to this person"}) return diff --git a/apps/db-adapter/internal/api/person_google.go b/apps/db-adapter/internal/api/person_google.go index 2bbd5f3..e66d87a 100644 --- a/apps/db-adapter/internal/api/person_google.go +++ b/apps/db-adapter/internal/api/person_google.go @@ -43,6 +43,7 @@ func (srv *server) CreatePersonByGoogleIdAndInviteCode(c *gin.Context, googleId ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer cancel() session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + defer closeSession(c.Request.Context(), session, srv.dbOpTimeout) qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer qCancel()