forked from heroiclabs/nakama
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpipeline_self.go
147 lines (133 loc) · 4.68 KB
/
pipeline_self.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// Copyright 2017 The Nakama Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package server
import (
"database/sql"
"encoding/json"
"go.uber.org/zap"
)
func (p *pipeline) selfFetch(logger *zap.Logger, session session, envelope *Envelope) {
var fullname sql.NullString
var handle sql.NullString
var email sql.NullString
var facebook sql.NullString
var google sql.NullString
var gamecenter sql.NullString
var steam sql.NullString
var customID sql.NullString
var timezone sql.NullString
var location sql.NullString
var lang sql.NullString
var metadata []byte
var avatarURL sql.NullString
var verifiedAt sql.NullInt64
var createdAt sql.NullInt64
var updatedAt sql.NullInt64
deviceIDs := make([]string, 0)
rows, err := p.db.Query(`
SELECT u.handle, u.fullname, u.avatar_url, u.lang, u.location, u.timezone, u.metadata,
u.email, u.facebook_id, u.google_id, u.gamecenter_id, u.steam_id, u.custom_id,
u.created_at, u.updated_at, u.verified_at,
ud.id
FROM users u
LEFT JOIN user_device ud ON u.id = ud.user_id
WHERE u.id = $1`,
session.UserID())
if err != nil {
logger.Error("Could not lookup user profile", zap.Error(err))
session.Send(ErrorMessageRuntimeException(envelope.CollationId, "Could not lookup user profile"), true)
return
}
defer rows.Close()
for rows.Next() {
var deviceID sql.NullString
err = rows.Scan(&handle, &fullname, &avatarURL, &lang, &location, &timezone, &metadata,
&email, &facebook, &google, &gamecenter, &steam, &customID,
&createdAt, &updatedAt, &verifiedAt, &deviceID)
if err != nil {
logger.Error("Error reading user profile", zap.Error(err))
session.Send(ErrorMessageRuntimeException(envelope.CollationId, "Error reading user profile"), true)
return
}
if deviceID.Valid {
deviceIDs = append(deviceIDs, deviceID.String)
}
}
if err = rows.Err(); err != nil {
logger.Error("Error reading user profile", zap.Error(err))
session.Send(ErrorMessageRuntimeException(envelope.CollationId, "Error reading user profile"), true)
return
}
s := &Self{
User: &User{
Id: session.UserID(),
Handle: handle.String,
Fullname: fullname.String,
AvatarUrl: avatarURL.String,
Lang: lang.String,
Location: location.String,
Timezone: timezone.String,
Metadata: string(metadata),
CreatedAt: createdAt.Int64,
UpdatedAt: updatedAt.Int64,
// The self user is assumed to be online.
LastOnlineAt: nowMs(),
},
Email: email.String,
DeviceIds: deviceIDs,
FacebookId: facebook.String,
GoogleId: google.String,
GamecenterId: gamecenter.String,
SteamId: steam.String,
CustomId: customID.String,
Verified: verifiedAt.Int64 > 0,
}
session.Send(&Envelope{CollationId: envelope.CollationId, Payload: &Envelope_Self{Self: &TSelf{Self: s}}}, true)
}
func (p *pipeline) selfUpdate(logger *zap.Logger, session session, envelope *Envelope) {
update := envelope.GetSelfUpdate()
// Validate any input possible before we hit database.
if update.Handle == "" && update.Fullname == "" && update.Timezone == "" && update.Location == "" && update.Lang == "" && len(update.Metadata) == 0 && update.AvatarUrl == "" {
session.Send(ErrorMessageBadInput(envelope.CollationId, "No fields to update"), true)
return
}
if len(update.Metadata) != 0 {
// Make this `var js interface{}` if we want to allow top-level JSON arrays.
var maybeJSON map[string]interface{}
if json.Unmarshal([]byte(update.Metadata), &maybeJSON) != nil {
session.Send(ErrorMessageBadInput(envelope.CollationId, "Metadata must be a valid JSON object"), true)
return
}
}
// Run the update.
code, err := SelfUpdate(logger, p.db, []*SelfUpdateOp{&SelfUpdateOp{
UserId: session.UserID(),
Handle: update.Handle,
Fullname: update.Fullname,
Timezone: update.Timezone,
Location: update.Location,
Lang: update.Lang,
Metadata: []byte(update.Metadata),
AvatarUrl: update.AvatarUrl,
}})
if err != nil {
session.Send(ErrorMessage(envelope.CollationId, code, err.Error()), true)
return
}
// Update handle in session and any presences, if a handle update was processed.
if update.Handle != "" {
session.SetHandle(update.Handle)
}
session.Send(&Envelope{CollationId: envelope.CollationId}, true)
}