feat: allow viewing user profile QR codes
This commit is contained in:
@@ -4196,6 +4196,148 @@ func TestServeIMUserProfile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMUserQRCodes(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
expectIMBearer(t, ctrl, "token-1", 7, 1)
|
||||
oldUsers := store.Users
|
||||
oldRelations := store.Relations
|
||||
oldProfiles := store.Profiles
|
||||
users := mock_store.NewMockUsersPersistenceInterface(ctrl)
|
||||
peer := types.Uid(2)
|
||||
users.EXPECT().Get(types.TenantID(7), peer).Return(&types.User{
|
||||
ObjHeader: types.ObjHeader{Id: peer.String()},
|
||||
TenantID: 7,
|
||||
Public: map[string]any{"display_name": "Alice"},
|
||||
}, nil)
|
||||
store.Users = users
|
||||
store.Relations = &testRelationsStore{context: &types.RelationshipContext{
|
||||
TenantID: 7,
|
||||
UserID: 1,
|
||||
PeerID: peer,
|
||||
Topic: types.Uid(1).P2PName(peer),
|
||||
Relationship: types.RelationshipFriend,
|
||||
CanSend: true,
|
||||
}}
|
||||
store.Profiles = &testProfilesStore{}
|
||||
defer func() {
|
||||
store.Users = oldUsers
|
||||
store.Relations = oldRelations
|
||||
store.Profiles = oldProfiles
|
||||
}()
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/users/"+peer.UserId()+"/qrcodes", bytes.NewBufferString(`{"expires_in_seconds":60}`))
|
||||
req.Header.Set("Authorization", "Bearer token-1")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
serveIMUserResource(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status: got %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
|
||||
if data["qr_token"] == "" || !strings.Contains(data["qr_payload"].(string), "purpose=add_friend") {
|
||||
t.Fatalf("unexpected qr response: %#v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMUserQRCodesByUsername(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
expectIMBearer(t, ctrl, "token-1", 7, 1)
|
||||
oldUsers := store.Users
|
||||
oldRelations := store.Relations
|
||||
oldProfiles := store.Profiles
|
||||
users := mock_store.NewMockUsersPersistenceInterface(ctrl)
|
||||
peer := types.Uid(2)
|
||||
peerUser := &types.User{
|
||||
ObjHeader: types.ObjHeader{Id: peer.String()},
|
||||
TenantID: 7,
|
||||
Public: map[string]any{"display_name": "Alice", "public_account": "alice001"},
|
||||
}
|
||||
users.EXPECT().Get(types.TenantID(7), peer).Return(peerUser, nil)
|
||||
store.Users = users
|
||||
store.Relations = &testRelationsStore{
|
||||
context: &types.RelationshipContext{
|
||||
TenantID: 7,
|
||||
UserID: 1,
|
||||
PeerID: peer,
|
||||
Topic: types.Uid(1).P2PName(peer),
|
||||
Relationship: types.RelationshipFriend,
|
||||
CanSend: true,
|
||||
},
|
||||
searchResults: []types.UserSearchItem{{User: peerUser, Relationship: types.RelationshipFriend}},
|
||||
}
|
||||
store.Profiles = &testProfilesStore{}
|
||||
defer func() {
|
||||
store.Users = oldUsers
|
||||
store.Relations = oldRelations
|
||||
store.Profiles = oldProfiles
|
||||
}()
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/users/alice001/qrcodes", bytes.NewBufferString(`{"expires_in_seconds":60}`))
|
||||
req.Header.Set("Authorization", "Bearer token-1")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
serveIMUserResource(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status: got %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
|
||||
token := data["qr_token"].(string)
|
||||
resolved, err := parseIMQRCodeToken(token, "add_friend", time.Now().UTC())
|
||||
if err != nil {
|
||||
t.Fatalf("parse token: %v", err)
|
||||
}
|
||||
if resolved.UserID != peer.UserId() {
|
||||
t.Fatalf("token user id: got %s, want %s", resolved.UserID, peer.UserId())
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMUserQRCodesRespectsPrivacy(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
expectIMBearer(t, ctrl, "token-1", 7, 1)
|
||||
oldUsers := store.Users
|
||||
oldRelations := store.Relations
|
||||
oldProfiles := store.Profiles
|
||||
users := mock_store.NewMockUsersPersistenceInterface(ctrl)
|
||||
peer := types.Uid(2)
|
||||
users.EXPECT().Get(types.TenantID(7), peer).Return(&types.User{
|
||||
ObjHeader: types.ObjHeader{Id: peer.String()},
|
||||
TenantID: 7,
|
||||
}, nil)
|
||||
store.Users = users
|
||||
store.Relations = &testRelationsStore{context: &types.RelationshipContext{
|
||||
TenantID: 7,
|
||||
UserID: 1,
|
||||
PeerID: peer,
|
||||
Topic: types.Uid(1).P2PName(peer),
|
||||
Relationship: types.RelationshipFriend,
|
||||
CanSend: true,
|
||||
}}
|
||||
store.Profiles = &testProfilesStore{privacy: &types.UserPrivacySettings{
|
||||
UserID: peer, AddMeMethods: map[string]bool{"account": true, "phone": true, "qr": false, "group": true},
|
||||
ProfileVisibility: "friends", LastSeenVisibility: "friends", ReadReceipts: true,
|
||||
}}
|
||||
defer func() {
|
||||
store.Users = oldUsers
|
||||
store.Relations = oldRelations
|
||||
store.Profiles = oldProfiles
|
||||
}()
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/v1/im/users/"+peer.UserId()+"/qrcodes", bytes.NewBufferString(`{}`))
|
||||
req.Header.Set("Authorization", "Bearer token-1")
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
serveIMUserResource(rec, req)
|
||||
|
||||
if rec.Code != http.StatusForbidden || decodeIMHTTPResponse(t, rec).Reason != imReasonPermissionDenied {
|
||||
t.Fatalf("privacy status: got %d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeIMBlocks(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
Reference in New Issue
Block a user