Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about how to have multiple users on an account #2993

Closed
akilisosa opened this issue Oct 31, 2024 · 8 comments
Closed

Question about how to have multiple users on an account #2993

akilisosa opened this issue Oct 31, 2024 · 8 comments
Labels
pending-community-response Issue is pending a response from the author or community. pending-triage question Further information is requested

Comments

@akilisosa
Copy link

akilisosa commented Oct 31, 2024

Amplify CLI Version

12.13.0

Question

I am confused about how to make an organization type of schema, and the right way to update roles and permissions on items. I'm on gen 1.

Lets say I create a website that is for publishers. They can create, books, essays, poems, and etc... There are owners, editors, and readers.

type Book @auth(rules:[{allow: groups, group: [Admin], [read, delete]}, {owner: [read, update, delete, create]}, {editors: [read, update, delete,]}, {public: [read], provider: apiKey }]) {
  title: String
  content: String
  editors: [String] #the editors id.
  owner: String
  }

... something similar for the other ones.

I have a different table for my editors, and a mechanism for getting their userID.

  type Editor @auth(rules:[{owner: [read, update, delete, create]}, {editors: [read, update,]},] {
  name: String
  userID: String
  owner: String
  }

Lets say I have created a 10 books, 22 essays, and 3 poems. Do i have to manually update all of the previous records with the user ID Whenever I create a new editor?

I know there are also groups, that can be updated in cognito like the "admin group" but that is across all of the books, from all the owners. If I added people to a group called editors, they would be able to edit everybody's book which i do not want.

I created an application called schedulevolunteers.com - to solve it in that one I had to create custom read operation for each one, that checked the nonProfit Entity table, to see if they had the permissions, or if they had been updated, and then update each record before they saw whatever it was they wanted to see, so they could make mutations. Is there an easier way to do this?

this i that schema so you can see a non trivial example. this was suppose to be for non profits - it helped one museum for a second but nobody use it anymore.

GraphQL Schema
type NonProfit
  @model
  @auth(
    rules: [
      { allow: owner, operations: [create, read, update, delete] }
      {
        allow: owner
        ownerField: "adminIDs"
        operations: [create, read, update, delete]
      }
      {
        allow: owner
        ownerField: "coordinatorIDs"
        operations: [create, read, update]
      }
      {
        allow: groups
        groups: ["Admin"]
        operations: [create, read, update, delete]
      }
      { allow: public, provider: apiKey, operations: [read] }
    ]
  ) {
  id: ID!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  title: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  nonProfitName: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  adminIDs: [String]
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        { allow: owner, ownerField: "coordinatorIDs", operations: [read] }
      ]
    )
  npAdmin: [NpAdmin]
    @hasMany(indexName: "byNonProfit", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )

  announcements: [Announcement]
    @hasMany(indexName: "byStartTime", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  description: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  volunteerURL: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  events: [Event]
    @hasMany(indexName: "byStartTime", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  #consider adding auth rules here
  volunteers: [Volunteer]
    @hasMany(indexName: "byVolunteer", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  coordinators: [Coordinator]
    @hasMany(indexName: "byEmail", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )

  #review coordinatorIDS
  coordinatorIDs: [String]
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  owner: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  roles: [Role]
    @hasMany(indexName: "byTitle", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  verifyrequested: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update]
        }
        { allow: private, operations: [read] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  outGoingEmail: String
  verifiedB: String
    @auth(
      rules: [
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
      ]
    )

  departments: [Department]
    @hasMany(indexName: "byDepartment", fields: ["id"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        { allow: public, provider: apiKey, operations: [read] }
        { allow: private, operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
}

type Department @model @auth(rules: [{ allow: private }]) {
  id: ID!
  nonProfitID: ID! @index(name: "byDepartment", sortKeyFields: ["department"])
  nonProfit: NonProfit! @belongsTo(fields: ["nonProfitID"])
  department: String
  name: String
  roles: [Role] @manyToMany(relationName: "DepartmentRoles")
  coordinators: [Coordinator]
    @manyToMany(relationName: "DepartmentCoordinators")
  volunteers: [Volunteer] @manyToMany(relationName: "DepartmentVolunteers")
}

# todo custom mutation custom query.
type UserSettings @model @auth(rules: [{ allow: owner }]) {
  id: ID!
  nonProfitID: ID
  volCalendarMode: String
  volCalendarDisplaySetting: String
  adminCalendarMode: String
  adminCalendarDisplaySetting: String
  owner: String!
}

type Event
  @model(mutations: null)
  @auth(
    rules: [
      { allow: owner, operations: [create, read, update, delete] }
      { allow: private, operations: [read] }
      { allow: public, operations: [read], provider: apiKey }
      {
        allow: owner
        ownerField: "coordinatorIDs"
        operations: [create, read, update, delete]
      }
      {
        allow: owner
        ownerField: "adminIDs"
        operations: [create, read, update, delete]
      }
    ]
  ) {
  coordinatorIDs: [String]
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  adminIDs: [String]
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  id: ID!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  title: String
  nonProfitTitle: String
  nonProfitID: ID!
    @index(name: "byStartTime", sortKeyFields: ["startTime"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  nonProfit: NonProfit!
    @belongsTo(fields: ["nonProfitID"])
    @auth(
      rules: [
        { allow: private }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  startTime: AWSDateTime!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  endTime: AWSDateTime!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  allDay: Boolean
  role: String!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  roleID: ID!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  volunteer: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  volunteerEmail: String
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  volunteersNeeded: Int
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  volunteersCount: Int
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  filled: Boolean
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  autoFill: Boolean
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
  volunteers: [Applicant]
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
      ]
    )
    @hasMany(indexName: "byApplicant", fields: ["id"])
  collectRandomEmails: Boolean
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
        {
          allow: owner
          ownerField: "coordinatorIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        { allow: private, operations: [read] }
        { allow: public, provider: apiKey, operations: [read] }
      ]
    )
}

type Announcement
  @model(mutations: null)
  @auth(
    rules: [
      { allow: private }
      { allow: public, provider: apiKey, operations: [read] }
    ]
  ) {
  id: ID!
  title: String
  description: String
  urlLink: String
  startTime: AWSDateTime
  endTime: AWSDateTime
  nonProfitID: ID! @index(name: "byStartTime", sortKeyFields: ["startTime"])
  nonProfit: NonProfit! @belongsTo(fields: ["nonProfitID"])
}

type Applicant
  @model(queries: null, mutations: null, subscriptions: null)
  @auth(
    rules: [
      { allow: private }
      { allow: public, provider: apiKey, operations: [create, read] }
    ]
  ) {
  id: ID!
  name: String
  email: String @index(name: "byUserEmail", sortKeyFields: ["eventID"])
  volunteerID: String
  scheduled: Boolean
  eventID: ID! @index(name: "byApplicant", sortKeyFields: ["id"])
  event: Event! @belongsTo(fields: ["eventID"])
}

type Volunteer
  @model
  @auth(
    rules: [
      { allow: owner, operations: [create, read, update, delete] }
      { allow: owner, ownerField: "volunteerUserID", operations: [read] }
      {
        allow: owner
        ownerField: "adminIDs"
        operations: [create, read, update, delete]
      }
      {
        allow: groups
        groups: ["Admin"]
        operations: [create, read, update, delete]
      }
    ]
  ) {
  id: ID!
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: owner, ownerField: "volunteerUserID", operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  email: String @index(name: "byUserEmail", sortKeyFields: ["nonProfitID"])
  adminIDs: [String]
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update]
        }
        { allow: owner, ownerField: "volunteerUserID", operations: [read] }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  name: String
  pin: String
  active: String
  participant: String
  volunteerUserID: String
    @index(name: "byUserID", sortKeyFields: ["nonProfitID"])
  recieveEmail: Boolean
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        {
          allow: owner
          ownerField: "volunteerUserID"
          operations: [read, update]
        }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  roles: [Role] @manyToMany(relationName: "VolunteerRoles")
  roleIDs: [String]
  canScheduleOff: Boolean
  notes: String
  nonProfitID: ID!
    @index(name: "byVolunteer", sortKeyFields: ["name"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: owner, ownerField: "volunteerUserID", operations: [read] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  nonProfit: NonProfit!
    @belongsTo(fields: ["nonProfitID"])
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: owner, ownerField: "volunteerUserID", operations: [read] }
        {
          allow: owner
          ownerField: "adminIDs"
          operations: [create, read, update, delete]
        }
        {
          allow: groups
          groups: ["Admin"]
          operations: [create, read, update, delete]
        }
      ]
    )
  departments: [Department] @manyToMany(relationName: "DepartmentVolunteers")
  coordinators: [Coordinator] @manyToMany(relationName: "CoordinatorVolunteers")
}

type Role
  @model
  @auth(
    rules: [
      { allow: private }
      { allow: public, provider: apiKey, operations: [read] }
    ]
  ) {
  id: ID!
  title: String
  days: String
  frequency: String
  duration: String
  description: String
  nonProfitID: ID! @index(name: "byTitle", sortKeyFields: ["title"])
  nonProfit: NonProfit! @belongsTo(fields: ["nonProfitID"])
  department: [Department] @manyToMany(relationName: "DepartmentRoles")
  coordinators: [Coordinator] @manyToMany(relationName: "CoordinatorRoles")
  volunteers: [Volunteer] @manyToMany(relationName: "VolunteerRoles")
}

type NpAdmin
  @model
  @auth(
    rules: [
      { allow: owner, operations: [create, read, update, delete] }
      # { allow: owner, ownerField: "coordinatorIDs", operations: [create, read, update]} ,
      {
        allow: groups
        groups: ["Admin"]
        operations: [create, read, update, delete]
      }
      { allow: owner, ownerField: "userID", operations: [read, update] }
    ]
  ) {
  id: ID!
  email: String
    @index(name: "byUserEmail", sortKeyFields: ["userID", "nonProfitID"])
  userID: String
    @index(name: "byUserID", sortKeyFields: ["email", "nonProfitID"])
  name: String
  recieveEmail: Boolean
  createEventEmail: Boolean
  eventFilledEmail: Boolean
  eventAppliedEmail: Boolean
  nonProfitID: ID! @index(name: "byNonProfit", sortKeyFields: ["name"])
  nonProfit: NonProfit! @belongsTo(fields: ["nonProfitID"])
}

type Coordinator
  @model
  @auth(
    rules: [
      { allow: owner, operations: [create, read, update, delete] }
      # { allow: owner, ownerField: "coordinatorIDs", operations: [create, read, update]} ,
      {
        allow: groups
        groups: ["Admin"]
        operations: [create, read, update, delete]
      }
      { allow: owner, ownerField: "userID", operations: [read] }
    ]
  ) {
  id: ID!
  name: String!
  email: String! @index(name: "byUserEmail", sortKeyFields: ["nonProfitID"])
  userID: String
    @index(name: "byUserID", sortKeyFields: ["email", "nonProfitID"])
  createEventEmail: Boolean
  eventFilledEmail: Boolean
  eventAppliedEmail: Boolean
  recieveEmail: Boolean
    @auth(
      rules: [
        { allow: owner, operations: [create, read, update, delete] }
        { allow: owner, ownerField: "userID", operations: [read, update] }
      ]
    )
  roleIDs: [String]
  roles: [Role] @manyToMany(relationName: "CoordinatorRoles")
  nonProfitID: ID! @index(name: "byEmail", sortKeyFields: ["email"])
  nonProfit: NonProfit! @belongsTo(fields: ["nonProfitID"])
  department: [Department] @manyToMany(relationName: "DepartmentCoordinators")
  volunteers: [Volunteer] @manyToMany(relationName: "CoordinatorVolunteers")
}

type Query {
  getNonProfitEvents(input: GetNonProfitEventInput): ModelEventConnection
  getNonProfitEventsForPublic(
    input: GetNonProfitEventInput
  ): ModelEventConnection
  getEventsForPublicByNonProfitID(
    input: GetNonProfitEventInput
  ): ModelEventConnection @auth(rules: [{ allow: public, provider: iam }])
  getCoordinators(input: GetCoordinatorsInput): ModelCoordinatorConnection
  getVolunteers(input: GetVolunteersInput): ModelVolunteerConnection
}

type Mutation {
  #apply to events as volunteer
  fillEventRole(input: UpdateEventForNonProfitInput): Event
  fillEventRoleAsApplicant(input: UpdateEventForNonProfitInput): Event
  applyWithEmailPublic(input: ApplyWithEmailInput): Event
    @auth(rules: [{ allow: public, provider: apiKey }])
  applyAsApplicantWithEmailPublic(input: ApplyWithEmailInput): Event
    @auth(rules: [{ allow: public, provider: apiKey }])
  #crud for events
  createNonProfitEvent(input: CreateEventForNonProfitInput): Event
  createNonProfitEventAsCoordinator(
    input: CreateEventForNonProfitAsCoordinatorInput
  ): Event
  updateNonProfitEvent(input: UpdateEventForNonProfitInput): Event
  updateNonProfitEventAsCoordinator(
    input: UpdateEventForNonProfitAsCoordinatorInput
  ): Event
  deleteNonProfitEvent(input: DeleteNonProfitInput): Event
  deleteNonProfitEventAsCoordinator(
    input: DeleteNonProfitAsCoordinatorInput
  ): Event
  #Checks for applicants to events
  checkVolunteerForEvent(input: GetVolunteerForEventInput): Event
  checkVolunteerApplicantsForEvent(
    input: GetVolunteerForEventInput
  ): [Applicant]
  #crud for announcments
  createAnnouncement(input: CreateAnnouncementInput): Announcement
  updateAnnouncement(input: UpdateAnnouncementInput): Announcement
  deleteAnnouncement(input: DeleteAnnouncementInput): Announcement
  #link accounts.
  claimVolunteerAccount(input: ClaimVolunteerAccountInput): Volunteer
  linkCoordinatorAccounts(args: String): String
}
@akilisosa akilisosa added pending-triage question Further information is requested labels Oct 31, 2024
@bobbyu99
Copy link
Contributor

You can use @hasMany to establish that an editor can have multiple books, and @belongsTo to link a book back to the Editor model. For Example:

type Editor @model {
  ...
  books: [Book] @hasMany(indexName: "byEditor", fields: ["id"])
}

type Book @model {
  ...
  editorID: ID! @index(name: "byEditor")
  editor: Editor @belongsTo(fields: ["editorID"])
}

You need to create an Editor first before you can assign that editor to a Book (or other content types like Essays and Poems). When you create a new Book, you specify the editorID, which references the existing Editor's id. This establishes the relationship between the Book and the Editor in your database.

So,

Lets say I have created a 10 books, 22 essays, and 3 poems. Do i have to manually update all of the previous records with the user ID Whenever I create a new editor?

The answer is yes.

@bobbyu99
Copy link
Contributor

I created an application called schedulevolunteers.com - to solve it in that one I had to create custom read operation for each one, that checked the nonProfit Entity table, to see if they had the permissions, or if they had been updated, and then update each record before they saw whatever it was they wanted to see, so they could make mutations. Is there an easier way to do this?

The @auth directive can use editorID as the ownerField to enforce per-item permissions. Only the Editor whose id matches the editorID can perform certain operations. For example:

type Book @model
  @auth(rules: [
    ...
    { allow: owner, ownerField: "editorID", operations: [read, update, delete] },
  ]) {
  ...
  editorID: ID! @index(name: "byEditor")
  editor: Editor @belongsTo(fields: ["editorID"])
}

In this case, the owner rule uses editorID to determine ownership. Only the Editor with the matching id can read, update, or delete the Book.

@AnilMaktala AnilMaktala added Gen 2 and removed Gen 2 labels Oct 31, 2024
@akilisosa
Copy link
Author

Thanks for letting me know. @bobbyu99

I tried to explain this over some of the amplify live chats but they couldn't understand the scope of the problem. The current application I am building - it seems like this would be an expensive operation. Especially because some of the data points are just site visits and other similar small data points that add up very quickly.

Is there a different architecture approach to solve this other than just making the functions manually?

I could create a separate instance for each company that bought the solution right? like _____.app.com and then have them call in whenever i needed to change someone's permission to "editor" or some other "admin" equivalent without loosing to much time.

@bobbyu99
Copy link
Contributor

bobbyu99 commented Nov 1, 2024

Have you tried Dynamic group authorization?

For example:

  1. have the following schema:
type Book @model
  @auth(rules: [
    ...
    { allow: groups, groupsField: "editors", operations: [read, update, delete] },
  ]) {
  id: ID!
  title: String!
  content: String
  editors: [String]
}
  1. create a group in Cognito like editors-123
  2. create a book:
{
  "id": "book1",
  "title": "Book Title",
  "content": "Book Content",
  "editors": ["editors-123"]
}
  1. create a new editor and add the editor to the group editors-123

Since access is granted based on group membership, adding a new editor to the group editors-123 in Cognito immediately gives them access to perform read, update, delete on all Books where editors field includes editors-123.

@akilisosa
Copy link
Author

@bobbyu99

No i haven't tried this yet. I will have to do some backfilling it seems like, but this could work.

Is there documentation on how to enable a user to create and add people to those dynamic groups, like from a lambda function invoked by a custom mutation?

@bobbyu99
Copy link
Contributor

bobbyu99 commented Nov 7, 2024

I don't think there is a documentation for this. But you may find the following uesful:
CognitoIdentityProviderClient
AdminAddUserToGroupCommand
CreateGroupCommand

@AnilMaktala
Copy link
Member

@AnilMaktala AnilMaktala added the pending-community-response Issue is pending a response from the author or community. label Nov 7, 2024
Copy link

This issue is now closed. Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pending-community-response Issue is pending a response from the author or community. pending-triage question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants