Skip to content

Commit e6b27f1

Browse files
committed
feat: add helpers to users and organization models
1 parent 5631e7a commit e6b27f1

File tree

5 files changed

+122
-29
lines changed

5 files changed

+122
-29
lines changed

shard.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ shards:
5454

5555
multi_auth:
5656
git: https://github.com/spider-gazelle/multi_auth.git
57-
version: 1.2.0+git.commit.5fa8730425f04bea6eeae47fa99e38b9522265c2
57+
version: 1.2.0+git.commit.8cb43fb8064d7a0d2a6198e584b4d9b8a9ef4901
5858

5959
mysql:
6060
git: https://github.com/crystal-lang/crystal-mysql.git
@@ -66,7 +66,7 @@ shards:
6666

6767
pg-orm:
6868
git: https://github.com/spider-gazelle/pg-orm.git
69-
version: 2.0.1
69+
version: 2.0.3
7070

7171
pool:
7272
git: https://github.com/ysbaddaden/pool.git

spec/models/org_user_spec.cr

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,76 @@
11
require "../spec_helper"
22

3-
describe App::Models::OrganizationUser do
4-
org_user = App::Models::OrganizationUser.new
5-
org = App::Models::Organization.new
6-
user = App::Models::User.new
7-
8-
Spec.around_each do |test|
9-
org_user = App::Models::OrganizationUser.new
10-
org = App::Models::Organization.new
11-
org.name = "Testing"
12-
org.save!
13-
14-
user = App::Models::User.new
15-
user.name = "Testing"
16-
user.email = "steve@orguser.com"
17-
user.save!
18-
19-
test.run
20-
21-
org_user.destroy
22-
org.destroy
23-
user.destroy
24-
end
3+
module App::Models
4+
describe OrganizationUser do
5+
org = Organization.new
6+
user = User.new
7+
8+
Spec.around_each do |test|
9+
org = Organization.new(name: "Testing").save!
10+
user = User.new(name: "Testing", email: "steve@orguser.com").save!
11+
12+
test.run
13+
14+
org.destroy
15+
user.destroy
16+
end
17+
18+
it "should be able to associate a user with an organisation" do
19+
org.add user
20+
org.users.to_a.map(&.id).first?.should eq user.id
21+
user.organizations.first.id.should eq org.id
22+
end
23+
24+
it "should be able to associate multiple users with an organisation" do
25+
user2 = User.new(name: "User2", email: "user2@org.com").save!
26+
user3 = User.new(name: "User3", email: "user3@org.com").save!
27+
28+
org.add user
29+
org.add user2
30+
31+
org.users.map(&.id).to_set.should eq [user.id, user2.id].to_set
32+
user3.organizations.to_a.should be_empty
33+
34+
user2.destroy
35+
user3.destroy
36+
# we've left the original user
37+
OrganizationUser.all.count.should eq 1
38+
end
39+
40+
it "should be able to associate multiple organisations with a user" do
41+
org2 = Organization.new(name: "org2").save!
42+
org3 = Organization.new(name: "org3").save!
43+
44+
org.add user
45+
org2.add user
46+
47+
user.organizations.map(&.id).to_set.should eq [org.id, org2.id].to_set
48+
org3.users.to_a.should be_empty
49+
50+
org2.destroy
51+
org3.destroy
52+
# we've left the original org
53+
OrganizationUser.all.count.should eq 1
54+
end
55+
56+
it "use helper functions to manage users" do
57+
user2 = User.new(name: "User2", email: "user2@org.com").save!
58+
user3 = User.new(name: "User3", email: "user3@org.com").save!
59+
60+
org.add user
61+
org.add user2
62+
org.add user3
63+
org.users.map(&.id).to_set.should eq [user.id, user2.id, user3.id].to_set
64+
65+
org.remove user
66+
org.remove user2
67+
org.users.count.should eq 1
68+
org.remove user3
69+
org.users.count.should eq 0
70+
OrganizationUser.all.count.should eq 0
2571

26-
it "should be able to associate a user with an organisation" do
27-
org_user.user = user
28-
org_user.organization = org
29-
org_user.permission = App::Permissions::Admin
30-
org_user.save!
72+
user2.destroy
73+
user3.destroy
74+
end
3175
end
3276
end

src/models/organization.cr

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,39 @@ class App::Models::Organization < ::PgORM::Base
88
attribute owner_id : UUID?
99
belongs_to :owner, class_name: User
1010

11+
def users
12+
User.join(:inner, OrganizationUser, :user_id).where("organization_users.organization_id = ?", self.id)
13+
end
14+
15+
def remove(user : User)
16+
OrganizationUser.find!({user.id, self.id}).destroy
17+
end
18+
19+
def add(user : User, permission : App::Permissions = App::Permissions::User)
20+
OrganizationUser.new(
21+
user_id: user.id,
22+
organization_id: self.id,
23+
permission: permission
24+
).save!
25+
end
26+
27+
def invite(user : User, permission : App::Permissions = App::Permissions::User, expires : Time? = nil)
28+
OrganizationInvite.new(
29+
email: user.email,
30+
organization_id: self.id,
31+
permission: permission,
32+
expires: expires
33+
).save!
34+
end
35+
36+
def invite(email : String, permission : App::Permissions = App::Permissions::User, expires : Time? = nil)
37+
OrganizationInvite.new(
38+
email: email,
39+
organization_id: self.id,
40+
permission: permission,
41+
expires: expires
42+
).save!
43+
end
44+
1145
include PgORM::Timestamps
1246
end

src/models/organization_invite.cr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class App::Models::OrganizationInvite < ::PgORM::Base
99
default_primary_key id : UUID
1010

1111
# TODO:: email validation
12+
# TODO:: additionally add user_id invites
1213
attribute email : String
1314
attribute secret : String, mass_assignment: false
1415

@@ -20,4 +21,14 @@ class App::Models::OrganizationInvite < ::PgORM::Base
2021

2122
# generate a secret for this invite
2223
before_create { self.secret = UUID.random.to_s }
24+
25+
def accept!
26+
user = User.where(email: self.email.downcase).first
27+
org = self.organization
28+
29+
PgORM::Database.transaction do |_tx|
30+
org.add(user, permission)
31+
self.destroy
32+
end
33+
end
2334
end

src/models/user.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@ class App::Models::User < ::PgORM::Base
1313
self.email = email.strip.downcase
1414
self.name = name.strip
1515
end
16+
17+
def organizations
18+
Organization.join(:inner, OrganizationUser, :organization_id).where("organization_users.user_id = ?", self.id)
19+
end
1620
end

0 commit comments

Comments
 (0)