Simplified profile code.

This commit is contained in:
Kleissner
2021-09-28 05:39:38 +02:00
parent 9ef6a88512
commit 608dbf6f47
7 changed files with 203 additions and 375 deletions

View File

@@ -15,68 +15,63 @@ import (
// apiProfileData contains profile metadata stored on the blockchain. Any data is treated as untrusted and unverified by default.
type apiProfileData struct {
Fields []apiBlockRecordProfileField `json:"fields"` // All fields
Blobs []apiBlockRecordProfileBlob `json:"blobs"` // All blobs
Status int `json:"status"` // Status of the operation, only used when this structure is returned from the API. See core.BlockchainStatusX.
Fields []apiBlockRecordProfile `json:"fields"` // All fields
Status int `json:"status"` // Status of the operation, only used when this structure is returned from the API. See core.BlockchainStatusX.
}
// apiBlockRecordProfile provides information about the end user. Note that all profile data is arbitrary and shall be considered untrusted and unverified.
// To establish trust, the user must load Certificates into the blockchain that validate certain data.
type apiBlockRecordProfile struct {
Type uint16 `json:"type"` // See ProfileX constants.
// Depending on the exact type, one of the below fields is used for proper encoding:
Text string `json:"text"` // Text value. UTF-8 encoding.
Blob []byte `json:"blob"` // Binary data
}
/*
apiProfileList lists all users profile fields and blobs.
apiProfileList lists all users profile fields.
Request: GET /profile/list
Response: 200 with JSON structure apiProfileData
*/
func apiProfileList(w http.ResponseWriter, r *http.Request) {
fields, blobs, status := core.UserProfileList()
fields, status := core.UserProfileList()
result := apiProfileData{Status: status}
for n := range fields {
result.Fields = append(result.Fields, apiBlockRecordProfileField{Type: fields[n].Type, Text: fields[n].Text})
}
for n := range blobs {
result.Blobs = append(result.Blobs, apiBlockRecordProfileBlob{Type: blobs[n].Type, Data: blobs[n].Data})
result.Fields = append(result.Fields, blockRecordProfileToAPI(fields[n]))
}
EncodeJSON(w, r, result)
}
/*
apiProfileRead reads a specific users profile field or blob.
For the index see core.ProfileFieldX and core.ProfileBlobX constants.
apiProfileRead reads a specific users profile field. See core.ProfileX for recognized fields.
Request: GET /profile/read?field=[index] or &blob=[index]
Request: GET /profile/read?field=[index]
Response: 200 with JSON structure apiProfileData
*/
func apiProfileRead(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
fieldN, err1 := strconv.Atoi(r.Form.Get("field"))
blobN, err2 := strconv.Atoi(r.Form.Get("blob"))
if (err1 != nil && err2 != nil) || (err1 == nil && fieldN < 0) || (err2 == nil && blobN < 0) {
if err1 != nil || fieldN < 0 {
http.Error(w, "", http.StatusBadRequest)
return
}
var result apiProfileData
if err1 == nil {
var text string
if text, result.Status = core.UserProfileReadField(uint16(fieldN)); result.Status == core.BlockchainStatusOK {
result.Fields = append(result.Fields, apiBlockRecordProfileField{Type: uint16(fieldN), Text: text})
}
} else {
var data []byte
if data, result.Status = core.UserProfileReadBlob(uint16(blobN)); result.Status == core.BlockchainStatusOK {
result.Blobs = append(result.Blobs, apiBlockRecordProfileBlob{Type: uint16(blobN), Data: data})
}
var data []byte
if data, result.Status = core.UserProfileReadField(uint16(fieldN)); result.Status == core.BlockchainStatusOK {
result.Fields = append(result.Fields, blockRecordProfileToAPI(core.BlockRecordProfile{Type: uint16(fieldN), Data: data}))
}
EncodeJSON(w, r, result)
}
/*
apiProfileWrite writes profile fields or blobs.
For the index see core.ProfileFieldX and core.ProfileBlobX constants.
apiProfileWrite writes profile fields. See core.ProfileX for recognized fields.
Request: POST /profile/write with JSON structure apiProfileData
Response: 200 with JSON structure apiBlockchainBlockStatus
@@ -87,23 +82,19 @@ func apiProfileWrite(w http.ResponseWriter, r *http.Request) {
return
}
var profile core.BlockRecordProfile
var fields []core.BlockRecordProfile
for n := range input.Fields {
profile.Fields = append(profile.Fields, core.BlockRecordProfileField{Type: input.Fields[n].Type, Text: input.Fields[n].Text})
}
for n := range input.Blobs {
profile.Blobs = append(profile.Blobs, core.BlockRecordProfileBlob{Type: input.Blobs[n].Type, Data: input.Blobs[n].Data})
fields = append(fields, blockRecordProfileFromAPI(input.Fields[n]))
}
newHeight, newVersion, status := core.UserProfileWrite(profile)
newHeight, newVersion, status := core.UserProfileWrite(fields)
EncodeJSON(w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
}
/*
apiProfileDelete deletes profile fields or blobs identified by the types.
For the index see core.ProfileFieldX and core.ProfileBlobX constants.
apiProfileDelete deletes profile fields identified by the types. See core.ProfileX for recognized fields.
Request: POST /profile/delete with JSON structure apiProfileData
Response: 200 with JSON structure apiBlockchainBlockStatus
@@ -114,16 +105,13 @@ func apiProfileDelete(w http.ResponseWriter, r *http.Request) {
return
}
var fields, blobs []uint16
var fields []uint16
for n := range input.Fields {
fields = append(fields, input.Fields[n].Type)
}
for n := range input.Blobs {
blobs = append(blobs, input.Blobs[n].Type)
}
newHeight, newVersion, status := core.UserProfileDelete(fields, blobs)
newHeight, newVersion, status := core.UserProfileDelete(fields)
EncodeJSON(w, r, apiBlockchainBlockStatus{Status: status, Height: newHeight, Version: newVersion})
}
@@ -131,22 +119,34 @@ func apiProfileDelete(w http.ResponseWriter, r *http.Request) {
// --- conversion from core to API data ---
func blockRecordProfileToAPI(input core.BlockRecordProfile) (output apiBlockRecordProfile) {
for n := range input.Fields {
output.Fields = append(output.Fields, apiBlockRecordProfileField{Type: input.Fields[n].Type, Text: input.Fields[n].Text})
}
for n := range input.Blobs {
output.Blobs = append(output.Blobs, apiBlockRecordProfileBlob{Type: input.Blobs[n].Type, Data: input.Blobs[n].Data})
output.Type = input.Type
switch input.Type {
case core.ProfileName, core.ProfileEmail, core.ProfileWebsite, core.ProfileTwitter, core.ProfileYouTube, core.ProfileAddress:
output.Text = input.Text()
case core.ProfilePicture:
output.Blob = input.Data
default:
output.Blob = input.Data
}
return output
}
func blockRecordProfileFromAPI(input apiBlockRecordProfile) (output core.BlockRecordProfile) {
for n := range input.Fields {
output.Fields = append(output.Fields, core.BlockRecordProfileField{Type: input.Fields[n].Type, Text: input.Fields[n].Text})
}
for n := range input.Blobs {
output.Blobs = append(output.Blobs, core.BlockRecordProfileBlob{Type: input.Blobs[n].Type, Data: input.Blobs[n].Data})
output.Type = input.Type
switch input.Type {
case core.ProfileName, core.ProfileEmail, core.ProfileWebsite, core.ProfileTwitter, core.ProfileYouTube, core.ProfileAddress:
output.Data = []byte(input.Text)
case core.ProfilePicture:
output.Data = input.Blob
default:
output.Data = input.Blob
}
return output