aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhellekin <hellekin@cepheide.org>2020-10-05 21:59:34 +0200
committerhellekin <hellekin@cepheide.org>2020-10-05 21:59:34 +0200
commitd0efb8c068a86436359b3c20950d427c7a6a27cd (patch)
tree46b9c2405d4c97845d18b0e4c53551137e71afeb
parent48031dde29d6dc4a0ba84c445ae4c07627257d4a (diff)
downloadincommon-map-d0efb8c068a86436359b3c20950d427c7a6a27cd.tar.gz
Add Agent and Agency models
Since IN COMMON is about collective management of data we're using the concept of Agent to describe a group of users acting together. In ActivityPub terms, Agent will be the Actor when manipulating data, so that any individual User (or application) member of this Agent will be able to manipulate data on behalf of this Agent. Therefore a User has many Agencies, and an Agent as well: the Agency model allows not only to create a joint table between Agents and Users, but also to manage User roles within the related Agent. Roles are defined as: - observer: one who can read and review or flag data - editor: one who create or edit data - maintainer: one who can edit data and manage maps - leader: one who can manage roles A User may have zero or more roles in an Agent. A User without a Agency record for a specific Agent will only be able to 'observe' public data from this Agent. (Note that this is not currently specified, but matches existing reflection on Agents) https://doc.incommon.cc/#agents
-rw-r--r--app/models/agency.rb22
-rw-r--r--app/models/agent.rb4
-rw-r--r--db/migrate/20201005154908_create_agents.rb11
-rw-r--r--db/migrate/20201005155004_create_agencies.rb12
-rw-r--r--db/schema.rb35
5 files changed, 83 insertions, 1 deletions
diff --git a/app/models/agency.rb b/app/models/agency.rb
new file mode 100644
index 0000000..fe81687
--- /dev/null
+++ b/app/models/agency.rb
@@ -0,0 +1,22 @@
+class Agency < ApplicationRecord
+ include Bitfields
+
+ belongs_to :agent
+ belongs_to :user
+
+ bitfield :roles, :observer, :editor, :maintainer, :leader
+
+ class << self
+ # Grant role in agent to user
+ def grant(agent, user, role)
+ r = find_or_create_by(agent: agent, user: user)
+ r&.public_send("#{role}=", true) && r&.save
+ end
+
+ # Revoke role in agent from user
+ def revoke(agent, user, role)
+ r = find_by(agent: agent, user: user)
+ r&.public_send("#{role}=", false) && r&.save
+ end
+ end
+end
diff --git a/app/models/agent.rb b/app/models/agent.rb
new file mode 100644
index 0000000..bb33c1b
--- /dev/null
+++ b/app/models/agent.rb
@@ -0,0 +1,4 @@
+class Agent < ApplicationRecord
+ has_many :agencies
+ has_many :members, through: :agencies, source: :user
+end
diff --git a/db/migrate/20201005154908_create_agents.rb b/db/migrate/20201005154908_create_agents.rb
new file mode 100644
index 0000000..32792ee
--- /dev/null
+++ b/db/migrate/20201005154908_create_agents.rb
@@ -0,0 +1,11 @@
+class CreateAgents < ActiveRecord::Migration[6.0]
+ def change
+ create_table :agents do |t|
+ t.string :name
+ t.uuid :uuid
+
+ t.timestamps
+ end
+ add_index :agents, [:uuid], unique: true
+ end
+end
diff --git a/db/migrate/20201005155004_create_agencies.rb b/db/migrate/20201005155004_create_agencies.rb
new file mode 100644
index 0000000..ab7cb03
--- /dev/null
+++ b/db/migrate/20201005155004_create_agencies.rb
@@ -0,0 +1,12 @@
+class CreateAgencies < ActiveRecord::Migration[6.0]
+ def change
+ create_table :agencies do |t|
+ t.references :agent, null: false, foreign_key: true
+ t.references :user, null: false, foreign_key: true
+ t.integer :roles, default: 0, null: false, limit: 2
+
+ t.timestamps
+ end
+ add_index :agencies, [:agent_id, :user_id], unique: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b10373b..ef4f4cd 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,9 +10,42 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 0) do
+ActiveRecord::Schema.define(version: 2020_10_05_155004) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
+ create_table "agencies", force: :cascade do |t|
+ t.bigint "agent_id", null: false
+ t.bigint "user_id", null: false
+ t.integer "roles", limit: 2, default: 0, null: false
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["agent_id", "user_id"], name: "index_agencies_on_agent_id_and_user_id", unique: true
+ t.index ["agent_id"], name: "index_agencies_on_agent_id"
+ t.index ["user_id"], name: "index_agencies_on_user_id"
+ end
+
+ create_table "agents", force: :cascade do |t|
+ t.string "name"
+ t.uuid "uuid"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["uuid"], name: "index_agents_on_uuid", unique: true
+ end
+
+ create_table "users", force: :cascade do |t|
+ t.string "name"
+ t.string "username"
+ t.string "email"
+ t.bigint "external_id"
+ t.string "avatar_url"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["email"], name: "index_users_on_email", unique: true
+ t.index ["external_id"], name: "index_users_on_external_id", unique: true
+ end
+
+ add_foreign_key "agencies", "agents"
+ add_foreign_key "agencies", "users"
end