1
+ package admin
2
+
3
+ import (
4
+ "context"
5
+ "encoding/json"
6
+ "errors"
7
+ "fmt"
8
+ "net/http"
9
+ "strings"
10
+ "time"
11
+
12
+ "github.com/factly/kavach-server/action/admin/organisation"
13
+ "github.com/factly/kavach-server/model"
14
+ "github.com/factly/x/loggerx"
15
+ "github.com/factly/x/slugx"
16
+ "github.com/factly/x/validationx"
17
+ keto "github.com/factly/kavach-server/util/keto/relationTuple"
18
+ )
19
+
20
+ type requestBody struct {
21
+ UserId string `json:"userId"`
22
+ Traits traits `json:"traits"`
23
+ }
24
+
25
+ type traits struct {
26
+ Email string `json:"email"`
27
+ IsVerified bool `json:"is_verified"`
28
+ Name struct {
29
+ First string `json:"first"`
30
+ Last string `json:"last"`
31
+ } `json:"name"`
32
+ }
33
+
34
+
35
+ func afterRegistration (w http.ResponseWriter , r * http.Request ) {
36
+ var requestBody requestBody
37
+ err := json .NewDecoder (r .Body ).Decode (& requestBody )
38
+ if err != nil {
39
+ loggerx .Error (err )
40
+ return
41
+ }
42
+
43
+ email := requestBody .Traits .Email
44
+ firstName := requestBody .Traits .Name .First
45
+ lastName := requestBody .Traits .Name .Last
46
+
47
+ user := model.User {
48
+ // make email lowercase to avoid case sensitivity
49
+ Email : strings .ToLower (email ),
50
+ KID : requestBody .UserId ,
51
+ FirstName : firstName ,
52
+ LastName : lastName ,
53
+ DisplayName : firstName + " " + lastName ,
54
+ Slug : slugx .Make (firstName + " " + lastName ),
55
+ }
56
+
57
+ // check whether user exists
58
+ err = model .DB .Model (& model.User {}).Where (& model.User {
59
+ Email : user .Email ,
60
+ }).First (& user ).Error
61
+
62
+ // user exists so update user
63
+ if err == nil {
64
+ user .IsActive = true
65
+ err = model .DB .Model (& model.User {}).Where ("email = ?" , user .Email ).Updates (& user ).Error
66
+ if err != nil {
67
+ loggerx .Error (err )
68
+ return
69
+ }
70
+ }
71
+
72
+ if err != nil {
73
+ user .IsActive = true
74
+ // record does not exist so create new user
75
+ var count int64
76
+ err = model .DB .Model (& model.User {}).Where (& model.User {
77
+ Email : user .Email ,
78
+ }).Count (& count ).Error
79
+ if err != nil {
80
+ loggerx .Error (err )
81
+ return
82
+ }
83
+ if count == 0 {
84
+ err = model .DB .Create (& user ).Error
85
+ if err != nil {
86
+ loggerx .Error (err )
87
+ return
88
+ }
89
+ }
90
+ }
91
+
92
+ // check if user is invited by any organisation
93
+ invitations := make ([]model.Invitation , 0 )
94
+ model .DB .Model (& model.Invitation {}).Select ("invitations.*" ).Joins ("join users on invitations.invitee_id = users.id" ).Where ("users.email = ?" , email ).Where ("invitations.expired_at > ?" , time .Now ()).Find (& invitations )
95
+
96
+ if len (invitations ) > 0 {
97
+ return
98
+ }
99
+
100
+ // create organisation for user
101
+ org := organisation.Organisation {
102
+ Title : firstName + " " + lastName ,
103
+ Slug : slugx .Make (firstName + " " + lastName ),
104
+ Description : "Default Organisation" ,
105
+ IsIndividual : true ,
106
+ UserID : uint (user .ID ),
107
+ }
108
+
109
+ err = createOrganisation (org )
110
+ if err != nil {
111
+ loggerx .Error (err )
112
+ return
113
+ }
114
+
115
+ }
116
+
117
+ func createOrganisation (org organisation.Organisation ) error {
118
+ validationError := validationx .Check (org )
119
+ if validationError != nil {
120
+ return errors .New ("validation error" )
121
+ }
122
+
123
+ mediumID := & org .FeaturedMediumID
124
+ if org .FeaturedMediumID == 0 {
125
+ mediumID = nil
126
+ }
127
+
128
+ type contextKey string
129
+
130
+ const userContext contextKey = "organisation_user"
131
+
132
+ tx := model .DB .WithContext (context .WithValue (context .Background (), userContext , org .UserID )).Begin ()
133
+
134
+ organisation := & model.Organisation {
135
+ Title : org .Title ,
136
+ Slug : org .Slug ,
137
+ Description : org .Description ,
138
+ FeaturedMediumID : mediumID ,
139
+ IsIndividual : org .IsIndividual ,
140
+ }
141
+
142
+ err := tx .Model (& model.Organisation {}).Create (& organisation ).Error
143
+
144
+ if err != nil {
145
+ tx .Rollback ()
146
+ return err
147
+ }
148
+
149
+ tx .Model (& model.Organisation {}).Preload ("Medium" ).First (& organisation )
150
+
151
+ permission := model.OrganisationUser {}
152
+ permission .OrganisationID = uint (organisation .ID )
153
+ permission .UserID = uint (org .UserID )
154
+ permission .Role = "owner"
155
+
156
+ err = tx .Model (& model.OrganisationUser {}).Create (& permission ).Error
157
+
158
+ if err != nil {
159
+ tx .Rollback ()
160
+ return err
161
+ }
162
+
163
+ // creating the organisation-role: owner, on the keto api
164
+ tuple := & model.KetoRelationTupleWithSubjectID {
165
+ KetoSubjectSet : model.KetoSubjectSet {
166
+ Namespace : "organisations" ,
167
+ Object : fmt .Sprintf ("org:%d" , organisation .ID ),
168
+ Relation : "owner" ,
169
+ },
170
+ SubjectID : fmt .Sprintf ("%d" , org .UserID ),
171
+ }
172
+
173
+ err = keto .CreateRelationTupleWithSubjectID (tuple )
174
+ if err != nil {
175
+ tx .Rollback ()
176
+ return err
177
+ }
178
+
179
+ var result model.Organisation
180
+
181
+ if organisation != nil {
182
+ result = * organisation
183
+ }
184
+
185
+ result .OrganisationUsers = []model.OrganisationUser {permission }
186
+
187
+ tx .Commit ()
188
+
189
+ return nil
190
+ }
0 commit comments