more golint cleanup

This commit is contained in:
Roland Osborne 2022-07-22 22:47:09 -07:00
parent cee3975fbc
commit ccfa6d6c3b
5 changed files with 71 additions and 41 deletions

View File

@ -15,6 +15,7 @@ var wsExit = make(chan bool, 1)
var statusListener = make(map[uint][]chan<- []byte) var statusListener = make(map[uint][]chan<- []byte)
var upgrader = websocket.Upgrader{} var upgrader = websocket.Upgrader{}
//Status handler for websocket connection
func Status(w http.ResponseWriter, r *http.Request) { func Status(w http.ResponseWriter, r *http.Request) {
// accept websocket connection // accept websocket connection
@ -74,8 +75,8 @@ func Status(w http.ResponseWriter, r *http.Request) {
defer close(c) defer close(c)
// register channel for revisions // register channel for revisions
AddStatusListener(app.Account.ID, c) addStatusListener(app.Account.ID, c)
defer RemoveStatusListener(app.Account.ID, c) defer removeStatusListener(app.Account.ID, c)
// start ping pong ticker // start ping pong ticker
ticker := time.NewTicker(60 * time.Second) ticker := time.NewTicker(60 * time.Second)
@ -113,10 +114,12 @@ func getRevision(account *store.Account) Revision {
return r return r
} }
//ExitStatus closes websocket handler
func ExitStatus() { func ExitStatus() {
wsExit <- true wsExit <- true
} }
//SetStatus sends revision object on all account websockets
func SetStatus(account *store.Account) { func SetStatus(account *store.Account) {
// get revisions for the account // get revisions for the account
@ -140,7 +143,7 @@ func SetStatus(account *store.Account) {
} }
} }
func AddStatusListener(act uint, ch chan<- []byte) { func addStatusListener(act uint, ch chan<- []byte) {
// lock access to statusListener // lock access to statusListener
wsSync.Lock() wsSync.Lock()
@ -155,7 +158,7 @@ func AddStatusListener(act uint, ch chan<- []byte) {
} }
} }
func RemoveStatusListener(act uint, ch chan<- []byte) { func removeStatusListener(act uint, ch chan<- []byte) {
// lock access to statusListener // lock access to statusListener
wsSync.Lock() wsSync.Lock()

View File

@ -11,6 +11,7 @@ import (
"time" "time"
) )
//AccountLogin retrieves account specified by username and password
func AccountLogin(r *http.Request) (*store.Account, error) { func AccountLogin(r *http.Request) (*store.Account, error) {
// extract request auth // extract request auth
@ -33,6 +34,7 @@ func AccountLogin(r *http.Request) (*store.Account, error) {
return account, nil return account, nil
} }
//BearerAccountToken retrieves AccountToken object specified by authorization header
func BearerAccountToken(r *http.Request) (*store.AccountToken, error) { func BearerAccountToken(r *http.Request) (*store.AccountToken, error) {
// parse bearer authentication // parse bearer authentication
@ -50,6 +52,7 @@ func BearerAccountToken(r *http.Request) (*store.AccountToken, error) {
return &accountToken, nil return &accountToken, nil
} }
//AccessToken retrieves AccountToken specified by token query param
func AccessToken(r *http.Request) (*store.AccountToken, int, error) { func AccessToken(r *http.Request) (*store.AccountToken, int, error) {
// parse authentication token // parse authentication token
@ -69,6 +72,7 @@ func AccessToken(r *http.Request) (*store.AccountToken, int, error) {
return &accountToken, http.StatusOK, nil return &accountToken, http.StatusOK, nil
} }
//ParamAdminToken compares admin token with token query param
func ParamAdminToken(r *http.Request) (int, error) { func ParamAdminToken(r *http.Request) (int, error) {
// parse authentication token // parse authentication token
@ -91,6 +95,7 @@ func ParamAdminToken(r *http.Request) (int, error) {
return http.StatusOK, nil return http.StatusOK, nil
} }
//ParamAgentToken retrieves account specified by agent query param
func ParamAgentToken(r *http.Request, detail bool) (*store.Account, int, error) { func ParamAgentToken(r *http.Request, detail bool) (*store.Account, int, error) {
// parse authentication token // parse authentication token
@ -105,17 +110,15 @@ func ParamAgentToken(r *http.Request, detail bool) (*store.Account, int, error)
if err := store.DB.Preload("Account.AccountDetail").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil { if err := store.DB.Preload("Account.AccountDetail").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} else { } else {
if err := store.DB.Preload("Account").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil { if err := store.DB.Preload("Account").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} }
if app.Account.Disabled { if app.Account.Disabled {
@ -125,6 +128,7 @@ func ParamAgentToken(r *http.Request, detail bool) (*store.Account, int, error)
return &app.Account, http.StatusOK, nil return &app.Account, http.StatusOK, nil
} }
//BearerAppToken retrieves account specified by authorization header
func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) { func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) {
// parse bearer authentication // parse bearer authentication
@ -141,17 +145,15 @@ func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) {
if err := store.DB.Preload("Account.AccountDetail").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil { if err := store.DB.Preload("Account.AccountDetail").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} else { } else {
if err := store.DB.Preload("Account").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil { if err := store.DB.Preload("Account").Where("account_id = ? AND token = ?", target, access).First(&app).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} }
if app.Account.Disabled { if app.Account.Disabled {
@ -161,6 +163,7 @@ func BearerAppToken(r *http.Request, detail bool) (*store.Account, int, error) {
return &app.Account, http.StatusOK, nil return &app.Account, http.StatusOK, nil
} }
//ParseToken separates access token into its guid and random value parts
func ParseToken(token string) (string, string, error) { func ParseToken(token string) (string, string, error) {
split := strings.Split(token, ".") split := strings.Split(token, ".")
@ -170,6 +173,7 @@ func ParseToken(token string) (string, string, error) {
return split[0], split[1], nil return split[0], split[1], nil
} }
//ParamTokenType returns type of access token specified
func ParamTokenType(r *http.Request) string { func ParamTokenType(r *http.Request) string {
if r.FormValue(APPTokenContact) != "" { if r.FormValue(APPTokenContact) != "" {
return APPTokenContact return APPTokenContact
@ -189,6 +193,7 @@ func ParamTokenType(r *http.Request) string {
return "" return ""
} }
//ParamContactToken retrieves card specified by contact query param
func ParamContactToken(r *http.Request, detail bool) (*store.Card, int, error) { func ParamContactToken(r *http.Request, detail bool) (*store.Card, int, error) {
// parse authentication token // parse authentication token
@ -203,17 +208,15 @@ func ParamContactToken(r *http.Request, detail bool) (*store.Card, int, error) {
if err := store.DB.Preload("CardSlot").Preload("Account.AccountDetail").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil { if err := store.DB.Preload("CardSlot").Preload("Account.AccountDetail").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} else { } else {
if err := store.DB.Preload("CardSlot").Preload("Account").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil { if err := store.DB.Preload("CardSlot").Preload("Account").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} }
if card.Account.Disabled { if card.Account.Disabled {
@ -226,6 +229,7 @@ func ParamContactToken(r *http.Request, detail bool) (*store.Card, int, error) {
return &card, http.StatusOK, nil return &card, http.StatusOK, nil
} }
//BearerContactToken retrieves card specified by authorization header
func BearerContactToken(r *http.Request, detail bool) (*store.Card, int, error) { func BearerContactToken(r *http.Request, detail bool) (*store.Card, int, error) {
// parse bearer authentication // parse bearer authentication
@ -242,17 +246,15 @@ func BearerContactToken(r *http.Request, detail bool) (*store.Card, int, error)
if err := store.DB.Preload("Account.AccountDetail").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil { if err := store.DB.Preload("Account.AccountDetail").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} else { } else {
if err := store.DB.Preload("Account").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil { if err := store.DB.Preload("Account").Where("account_id = ? AND in_token = ?", target, access).First(&card).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) { if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, http.StatusNotFound, err return nil, http.StatusNotFound, err
} else {
return nil, http.StatusInternalServerError, err
} }
return nil, http.StatusInternalServerError, err
} }
} }
if card.Account.Disabled { if card.Account.Disabled {
@ -265,6 +267,7 @@ func BearerContactToken(r *http.Request, detail bool) (*store.Card, int, error)
return &card, http.StatusOK, nil return &card, http.StatusOK, nil
} }
//BasicCredentials extracts username and password set it credentials header
func BasicCredentials(r *http.Request) (string, []byte, error) { func BasicCredentials(r *http.Request) (string, []byte, error) {
var username string var username string

View File

@ -12,6 +12,7 @@ import (
"strings" "strings"
) )
//WriteResponse serialze and write json body for response
func WriteResponse(w http.ResponseWriter, v interface{}) { func WriteResponse(w http.ResponseWriter, v interface{}) {
body, err := json.Marshal(v) body, err := json.Marshal(v)
if err != nil { if err != nil {
@ -25,6 +26,7 @@ func WriteResponse(w http.ResponseWriter, v interface{}) {
} }
} }
//ReadResponse read and parse json response body
func ReadResponse(w *httptest.ResponseRecorder, v interface{}) error { func ReadResponse(w *httptest.ResponseRecorder, v interface{}) error {
resp := w.Result() resp := w.Result()
if resp.StatusCode != 200 { if resp.StatusCode != 200 {
@ -38,20 +40,24 @@ func ReadResponse(w *httptest.ResponseRecorder, v interface{}) error {
return nil return nil
} }
//SetBasicAuth sets basic auth in authorization header
func SetBasicAuth(r *http.Request, login string) { func SetBasicAuth(r *http.Request, login string) {
auth := base64.StdEncoding.EncodeToString([]byte(login)) auth := base64.StdEncoding.EncodeToString([]byte(login))
r.Header.Add("Authorization", "Basic "+auth) r.Header.Add("Authorization", "Basic "+auth)
} }
//SetBearerAuth sets bearer auth token in header
func SetBearerAuth(r *http.Request, token string) { func SetBearerAuth(r *http.Request, token string) {
r.Header.Add("Authorization", "Bearer "+token) r.Header.Add("Authorization", "Bearer "+token)
} }
//SetCredentials set basic auth in credentials header
func SetCredentials(r *http.Request, login string) { func SetCredentials(r *http.Request, login string) {
auth := base64.StdEncoding.EncodeToString([]byte(login)) auth := base64.StdEncoding.EncodeToString([]byte(login))
r.Header.Add("Credentials", "Basic "+auth) r.Header.Add("Credentials", "Basic "+auth)
} }
//ParseRequest read and parse json request body
func ParseRequest(r *http.Request, w http.ResponseWriter, obj interface{}) error { func ParseRequest(r *http.Request, w http.ResponseWriter, obj interface{}) error {
r.Body = http.MaxBytesReader(w, r.Body, APPBodyLimit) r.Body = http.MaxBytesReader(w, r.Body, APPBodyLimit)
dec := json.NewDecoder(r.Body) dec := json.NewDecoder(r.Body)
@ -59,6 +65,3 @@ func ParseRequest(r *http.Request, w http.ResponseWriter, obj interface{}) error
return dec.Decode(&obj) return dec.Decode(&obj)
} }
func EnableCors(w *http.ResponseWriter) {
(*w).Header().Set("Access-Control-Allow-Origin", "*")
}

View File

@ -28,7 +28,7 @@ func GenerateRsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey, string, error) {
} }
} }
//ExportRsaPrivateKeyAsPemString exports account private key //ExportRsaPrivateKeyAsPemStr exports account private key
func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string { func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
privkeyBytes := x509.MarshalPKCS1PrivateKey(privkey) privkeyBytes := x509.MarshalPKCS1PrivateKey(privkey)
privkeyPEM := pem.EncodeToMemory( privkeyPEM := pem.EncodeToMemory(

View File

@ -1,5 +1,6 @@
package databag package databag
//AccountProfile account profile view retrieved by admin
type AccountProfile struct { type AccountProfile struct {
AccountID uint32 `json:"accountId"` AccountID uint32 `json:"accountId"`
@ -18,6 +19,7 @@ type AccountProfile struct {
Disabled bool `json:"disabled"` Disabled bool `json:"disabled"`
} }
//AccountStatus server settings for account
type AccountStatus struct { type AccountStatus struct {
Disabled bool `json:"disabled"` Disabled bool `json:"disabled"`
@ -30,18 +32,12 @@ type AccountStatus struct {
Searchable bool `json:"searchable"` Searchable bool `json:"searchable"`
} }
//Announce initial message sent on websocket
type Announce struct { type Announce struct {
AppToken string `json:"appToken"` AppToken string `json:"appToken"`
} }
type App struct { //AppData describes app connected to account
ID string `json:"id"`
Revision int64 `json:"revision"`
Data *AppData `json:"data"`
}
type AppData struct { type AppData struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
@ -54,6 +50,7 @@ type AppData struct {
Attached int64 `json:"attached"` Attached int64 `json:"attached"`
} }
//Article slot for account data shared by group list
type Article struct { type Article struct {
ID string `json:"id"` ID string `json:"id"`
@ -62,6 +59,7 @@ type Article struct {
Data *ArticleData `json:"data"` Data *ArticleData `json:"data"`
} }
//ArticleData account data shared by group list
type ArticleData struct { type ArticleData struct {
DataType string `json:"dataType"` DataType string `json:"dataType"`
@ -74,10 +72,7 @@ type ArticleData struct {
Groups *IDList `json:"groups,omitempty"` Groups *IDList `json:"groups,omitempty"`
} }
type ArticleGroups struct { //Asset files associated with channel topic
Groups []string `json:"groups"`
}
type Asset struct { type Asset struct {
AssetID string `json:"assetId"` AssetID string `json:"assetId"`
@ -86,6 +81,7 @@ type Asset struct {
Status string `json:"status,omitempty"` Status string `json:"status,omitempty"`
} }
//Card slot for references to an account contact
type Card struct { type Card struct {
ID string `json:"id"` ID string `json:"id"`
@ -94,6 +90,7 @@ type Card struct {
Data *CardData `json:"data"` Data *CardData `json:"data"`
} }
//CardData account contact data
type CardData struct { type CardData struct {
DetailRevision int64 `json:"detailRevision"` DetailRevision int64 `json:"detailRevision"`
@ -112,6 +109,7 @@ type CardData struct {
CardProfile *CardProfile `json:"cardProfile,omitempty"` CardProfile *CardProfile `json:"cardProfile,omitempty"`
} }
//CardDetail values set for associated contact
type CardDetail struct { type CardDetail struct {
Status string `json:"status"` Status string `json:"status"`
@ -122,6 +120,7 @@ type CardDetail struct {
Groups []string `json:"groups,omitempty"` Groups []string `json:"groups,omitempty"`
} }
//CardProfile profile for account contact
type CardProfile struct { type CardProfile struct {
GUID string `json:"guid"` GUID string `json:"guid"`
@ -140,12 +139,14 @@ type CardProfile struct {
Node string `json:"node"` Node string `json:"node"`
} }
//ChannelContacts ids for cards and groups with whom channel is shared
type ChannelContacts struct { type ChannelContacts struct {
Groups []string `json:"groups"` Groups []string `json:"groups"`
Cards []string `json:"cards"` Cards []string `json:"cards"`
} }
//Channel slot for communication channel
type Channel struct { type Channel struct {
ID string `json:"id"` ID string `json:"id"`
@ -154,6 +155,7 @@ type Channel struct {
Data *ChannelData `json:"data"` Data *ChannelData `json:"data"`
} }
//ChannelData communication channel data
type ChannelData struct { type ChannelData struct {
DetailRevision int64 `json:"detailRevision"` DetailRevision int64 `json:"detailRevision"`
@ -164,6 +166,7 @@ type ChannelData struct {
ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"` ChannelDetail *ChannelDetail `json:"channelDetail,omitempty"`
} }
//ChannelDetail description of channel
type ChannelDetail struct { type ChannelDetail struct {
DataType string `json:"dataType"` DataType string `json:"dataType"`
@ -178,10 +181,12 @@ type ChannelDetail struct {
Members []string `json:"members"` Members []string `json:"members"`
} }
//ChannelSummary latest topic posted on channel
type ChannelSummary struct { type ChannelSummary struct {
LastTopic *TopicDetail `json:"lastTopic,omitempty"` LastTopic *TopicDetail `json:"lastTopic,omitempty"`
} }
//ChannelParams params used when creating a channel
type ChannelParams struct { type ChannelParams struct {
DataType string `json:"dataType"` DataType string `json:"dataType"`
@ -192,10 +197,12 @@ type ChannelParams struct {
Cards []string `json:"cards"` Cards []string `json:"cards"`
} }
//Claim token to verify for 3rd party authentication
type Claim struct { type Claim struct {
Token string `json:"token"` Token string `json:"token"`
} }
//Connect data exchanged in a contact connection message
type Connect struct { type Connect struct {
Contact string `json:"contact"` Contact string `json:"contact"`
@ -224,6 +231,7 @@ type Connect struct {
Node string `json:"node,omitempty"` Node string `json:"node,omitempty"`
} }
//ContactStatus status of contact returned after connection message
type ContactStatus struct { type ContactStatus struct {
Token string `json:"token,omitempty"` Token string `json:"token,omitempty"`
@ -238,6 +246,7 @@ type ContactStatus struct {
Status string `json:"status"` Status string `json:"status"`
} }
//DataMessage general structure holding signed messages
type DataMessage struct { type DataMessage struct {
Message string `json:"message"` Message string `json:"message"`
@ -250,10 +259,12 @@ type DataMessage struct {
SignatureType string `json:"signatureType"` SignatureType string `json:"signatureType"`
} }
//Disconnect data exchanged when closing connection
type Disconnect struct { type Disconnect struct {
Contact string `json:"contact"` Contact string `json:"contact"`
} }
//Group slot for holding a contact group alias
type Group struct { type Group struct {
ID string `json:"id"` ID string `json:"id"`
@ -262,6 +273,7 @@ type Group struct {
Data *GroupData `json:"data,omitempty"` Data *GroupData `json:"data,omitempty"`
} }
//GroupData a contact group alias
type GroupData struct { type GroupData struct {
DataType string `json:"dataType"` DataType string `json:"dataType"`
@ -272,6 +284,7 @@ type GroupData struct {
Updated int64 `json:"updated"` Updated int64 `json:"updated"`
} }
//Identity data exchanged in a profile message
type Identity struct { type Identity struct {
Revision int64 `json:"revision"` Revision int64 `json:"revision"`
@ -290,16 +303,19 @@ type Identity struct {
Node string `json:"node"` Node string `json:"node"`
} }
//IDList general list of ids
type IDList struct { type IDList struct {
IDs []string `json:"ids"` IDs []string `json:"ids"`
} }
//LoginAccess response object when app is associated
type LoginAccess struct { type LoginAccess struct {
AppToken string `json:"appToken"` AppToken string `json:"appToken"`
Created int64 `json:"created"` Created int64 `json:"created"`
} }
//NodeConfig node configuration values
type NodeConfig struct { type NodeConfig struct {
Domain string `json:"domain"` Domain string `json:"domain"`
@ -310,6 +326,7 @@ type NodeConfig struct {
AccountStorage int64 `json:"accountStorage"` AccountStorage int64 `json:"accountStorage"`
} }
//Profile public attributes of account
type Profile struct { type Profile struct {
GUID string `json:"guid"` GUID string `json:"guid"`
@ -330,6 +347,7 @@ type Profile struct {
Node string `json:"node"` Node string `json:"node"`
} }
//ProfileData subset of profile attributes to set
type ProfileData struct { type ProfileData struct {
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
@ -338,6 +356,7 @@ type ProfileData struct {
Location string `json:"location,omitempty"` Location string `json:"location,omitempty"`
} }
//Revision revision of each account module
type Revision struct { type Revision struct {
Account int64 `json:"account"` Account int64 `json:"account"`
@ -352,6 +371,7 @@ type Revision struct {
Card int64 `json:"card"` Card int64 `json:"card"`
} }
//SignedData object serialized in message
type SignedData struct { type SignedData struct {
GUID string `json:"guid"` GUID string `json:"guid"`
@ -362,12 +382,14 @@ type SignedData struct {
Value string `json:"value"` Value string `json:"value"`
} }
//Subject payload of attribute, channel, topic or tag
type Subject struct { type Subject struct {
DataType string `json:"dataType"` DataType string `json:"dataType"`
Data string `json:"data"` Data string `json:"data"`
} }
//Tag slot for tags associated with topic
type Tag struct { type Tag struct {
ID string `json:"id"` ID string `json:"id"`
@ -376,6 +398,7 @@ type Tag struct {
Data *TagData `json:"data"` Data *TagData `json:"data"`
} }
//TagData data associated with topic
type TagData struct { type TagData struct {
GUID string `json:"guid"` GUID string `json:"guid"`
@ -388,6 +411,7 @@ type TagData struct {
Updated int64 `json:"updated"` Updated int64 `json:"updated"`
} }
//Topic slot for object associated with channel
type Topic struct { type Topic struct {
ID string `json:"id"` ID string `json:"id"`
@ -396,6 +420,7 @@ type Topic struct {
Data *TopicData `json:"data"` Data *TopicData `json:"data"`
} }
//TopicData data and revision of posted topic and tags
type TopicData struct { type TopicData struct {
DetailRevision int64 `json:"detailRevision"` DetailRevision int64 `json:"detailRevision"`
@ -404,6 +429,7 @@ type TopicData struct {
TopicDetail *TopicDetail `json:"topicDetail,omitempty"` TopicDetail *TopicDetail `json:"topicDetail,omitempty"`
} }
//TopicDetail payload of topic
type TopicDetail struct { type TopicDetail struct {
GUID string `json:"guid"` GUID string `json:"guid"`
@ -420,8 +446,3 @@ type TopicDetail struct {
Transform string `json:"transform,omitempty"` Transform string `json:"transform,omitempty"`
} }
type TopicTags struct {
TagCount int32 `json:"tagCount"`
TagUpdated int64 `json:"tagUpdated"`
}