mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-12 01:13:10 -06:00
Profile retrieval
This commit is contained in:
parent
b13cbb18fb
commit
490d14ebe7
|
|
@ -23,6 +23,7 @@ type Account struct {
|
||||||
UserID string
|
UserID string
|
||||||
Localpart string
|
Localpart string
|
||||||
ServerName gomatrixserverlib.ServerName
|
ServerName gomatrixserverlib.ServerName
|
||||||
|
Profile *Profile
|
||||||
// TODO: Other flags like IsAdmin, IsGuest
|
// TODO: Other flags like IsAdmin, IsGuest
|
||||||
// TODO: Devices
|
// TODO: Devices
|
||||||
// TODO: Associations (e.g. with application services)
|
// TODO: Associations (e.g. with application services)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2017 Vector Creations Ltd
|
||||||
|
//
|
||||||
|
// 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 authtypes
|
||||||
|
|
||||||
|
// Profile represents the profile for a Matrix account on this home server.
|
||||||
|
type Profile struct {
|
||||||
|
Localpart string
|
||||||
|
DisplayName string
|
||||||
|
AvatarURL string
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright 2017 Vector Creations Ltd
|
||||||
|
//
|
||||||
|
// 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 accounts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
const profilesSchema = `
|
||||||
|
-- Stores data about accounts profiles.
|
||||||
|
CREATE TABLE IF NOT EXISTS profiles (
|
||||||
|
-- The Matrix user ID localpart for this account
|
||||||
|
localpart TEXT NOT NULL PRIMARY KEY,
|
||||||
|
-- The display name for this account
|
||||||
|
display_name TEXT,
|
||||||
|
-- The URL of the avatar for this account
|
||||||
|
avatar_url TEXT
|
||||||
|
);
|
||||||
|
`
|
||||||
|
|
||||||
|
const insertProfileSQL = "" +
|
||||||
|
"INSERT INTO profiles(localpart, display_name, avatar_url) VALUES ($1, $2, $3)"
|
||||||
|
|
||||||
|
const selectProfileByLocalpartSQL = "" +
|
||||||
|
"SELECT localpart, display_name, avatar_url FROM profiles WHERE localpart = $1"
|
||||||
|
|
||||||
|
const setAvatarURLSQL = "" +
|
||||||
|
"UPDATE profiles SET avatar_url = $1 WHERE localpart = $2"
|
||||||
|
|
||||||
|
type profilesStatements struct {
|
||||||
|
insertProfileStmt *sql.Stmt
|
||||||
|
selectProfileByLocalpartStmt *sql.Stmt
|
||||||
|
setAvatarURLStmt *sql.Stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *profilesStatements) prepare(db *sql.DB) (err error) {
|
||||||
|
_, err = db.Exec(profilesSchema)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.insertProfileStmt, err = db.Prepare(insertProfileSQL); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.selectProfileByLocalpartStmt, err = db.Prepare(selectProfileByLocalpartSQL); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if s.setAvatarURLStmt, err = db.Prepare(setAvatarURLSQL); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *profilesStatements) insertProfile(localpart string) (err error) {
|
||||||
|
_, err = s.insertProfileStmt.Exec(localpart, "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *profilesStatements) selectProfileByLocalpart(localpart string) (*authtypes.Profile, error) {
|
||||||
|
var profile authtypes.Profile
|
||||||
|
err := s.selectProfileByLocalpartStmt.QueryRow(localpart).Scan(&profile.Localpart, &profile.DisplayName, &profile.AvatarURL)
|
||||||
|
return &profile, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *profilesStatements) setAvatarURL(localpart string, avatarURL string) (err error) {
|
||||||
|
_, err = s.setAvatarURLStmt.Exec(avatarURL, localpart)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@ import (
|
||||||
type Database struct {
|
type Database struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
accounts accountsStatements
|
accounts accountsStatements
|
||||||
|
profiles profilesStatements
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase creates a new accounts database
|
// NewDatabase creates a new accounts database
|
||||||
|
|
@ -41,7 +42,11 @@ func NewDatabase(dataSourceName string, serverName gomatrixserverlib.ServerName)
|
||||||
if err = a.prepare(db, serverName); err != nil {
|
if err = a.prepare(db, serverName); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Database{db, a}, nil
|
p := profilesStatements{}
|
||||||
|
if err = p.prepare(db); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Database{db, a, p}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAccountByPassword returns the account associated with the given localpart and password.
|
// GetAccountByPassword returns the account associated with the given localpart and password.
|
||||||
|
|
@ -57,6 +62,10 @@ func (d *Database) GetAccountByPassword(localpart, plaintextPassword string) (*a
|
||||||
return d.accounts.selectAccountByLocalpart(localpart)
|
return d.accounts.selectAccountByLocalpart(localpart)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Database) GetProfileByLocalpart(localpart string) (*authtypes.Profile, error) {
|
||||||
|
return d.profiles.selectProfileByLocalpart(localpart)
|
||||||
|
}
|
||||||
|
|
||||||
// CreateAccount makes a new account with the given login name and password. If no password is supplied,
|
// CreateAccount makes a new account with the given login name and password. If no password is supplied,
|
||||||
// the account will be a passwordless account.
|
// the account will be a passwordless account.
|
||||||
func (d *Database) CreateAccount(localpart, plaintextPassword string) (*authtypes.Account, error) {
|
func (d *Database) CreateAccount(localpart, plaintextPassword string) (*authtypes.Account, error) {
|
||||||
|
|
@ -64,6 +73,9 @@ func (d *Database) CreateAccount(localpart, plaintextPassword string) (*authtype
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if err := d.profiles.insertProfile(localpart); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return d.accounts.insertAccount(localpart, hash)
|
return d.accounts.insertAccount(localpart, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2017 Vector Creations Ltd
|
||||||
|
//
|
||||||
|
// 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 readers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
||||||
|
// "github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
// "github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
type profileResponse struct {
|
||||||
|
AvatarURL string `json:"avatar_url"`
|
||||||
|
DisplayName string `json:"displayname"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Profile(
|
||||||
|
req *http.Request, accountDB *accounts.Database, userID string,
|
||||||
|
) util.JSONResponse {
|
||||||
|
if req.Method == "GET" {
|
||||||
|
localpart := getLocalPart(userID)
|
||||||
|
profile, err := accountDB.GetProfileByLocalpart(localpart)
|
||||||
|
if err == nil {
|
||||||
|
res := profileResponse{
|
||||||
|
AvatarURL: profile.AvatarURL,
|
||||||
|
DisplayName: profile.DisplayName,
|
||||||
|
}
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 200,
|
||||||
|
JSON: res,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 500,
|
||||||
|
JSON: jsonerror.Unknown("Failed to load user profile"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 405,
|
||||||
|
JSON: jsonerror.NotFound("Bad method"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocalPart(userID string) string {
|
||||||
|
if !strings.HasPrefix(userID, "@") {
|
||||||
|
panic(fmt.Errorf("Invalid user ID"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the part before ":"
|
||||||
|
username := strings.Split(userID, ":")[0]
|
||||||
|
// Return the part after the "@"
|
||||||
|
return strings.Split(username, "@")[1]
|
||||||
|
}
|
||||||
|
|
@ -164,10 +164,8 @@ func Setup(
|
||||||
r0mux.Handle("/profile/{userID}",
|
r0mux.Handle("/profile/{userID}",
|
||||||
common.MakeAPI("profile", func(req *http.Request) util.JSONResponse {
|
common.MakeAPI("profile", func(req *http.Request) util.JSONResponse {
|
||||||
// TODO: Get profile data for user ID
|
// TODO: Get profile data for user ID
|
||||||
return util.JSONResponse{
|
vars := mux.Vars(req)
|
||||||
Code: 200,
|
return readers.Profile(req, accountDB, vars["userID"])
|
||||||
JSON: struct{}{},
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -237,13 +235,6 @@ func Setup(
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
r0mux.Handle("/profile/{userID}/displayname",
|
|
||||||
common.MakeAPI("profile_displayname", func(req *http.Request) util.JSONResponse {
|
|
||||||
// TODO: Set and get the displayname
|
|
||||||
return util.JSONResponse{Code: 200, JSON: struct{}{}}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
r0mux.Handle("/user/{userID}/account_data/{type}",
|
r0mux.Handle("/user/{userID}/account_data/{type}",
|
||||||
common.MakeAPI("user_account_data", func(req *http.Request) util.JSONResponse {
|
common.MakeAPI("user_account_data", func(req *http.Request) util.JSONResponse {
|
||||||
// TODO: Set and get the account_data
|
// TODO: Set and get the account_data
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue