github.com/decred/politeia@v1.4.0/politeiad/backend/backend.go (about) 1 // Copyright (c) 2017-2019 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package backend 6 7 import ( 8 "errors" 9 "fmt" 10 "regexp" 11 12 v1 "github.com/decred/politeia/politeiad/api/v1" 13 ) 14 15 var ( 16 // ErrRecordNotFound is emitted when a record could not be found 17 ErrRecordNotFound = errors.New("record not found") 18 19 // ErrRecordFound is emitted when a record is found while none was 20 // expected. 21 ErrRecordFound = errors.New("record found") 22 23 // ErrFileNotFound is emitted when a file inside a record could not be 24 // found 25 ErrFileNotFound = errors.New("file not found") 26 27 // ErrShutdown is emitted when the backend is shutting down. 28 ErrShutdown = errors.New("backend is shutting down") 29 30 // ErrNoChanges there are no changes to the record. 31 ErrNoChanges = errors.New("no changes to record") 32 33 // ErrChangesRecord is returned when a record would change when not 34 // expected. 35 ErrChangesRecord = errors.New("changes record") 36 37 // ErrRecordArchived is returned when an update was attempted on a 38 // archived record. 39 ErrRecordArchived = errors.New("record is archived") 40 41 // ErrJournalsNotReplayed is returned when the journals have not been replayed 42 // and the subsequent code expect it to be replayed 43 ErrJournalsNotReplayed = errors.New("journals have not been replayed") 44 45 // Plugin names must be all lowercase letters and have a length of <20 46 PluginRE = regexp.MustCompile(`^[a-z]{1,20}$`) 47 ) 48 49 // ContentVerificationError is returned when a submitted record contains 50 // unacceptable file formats or corrupt data. 51 type ContentVerificationError struct { 52 ErrorCode v1.ErrorStatusT 53 ErrorContext []string 54 } 55 56 func (c ContentVerificationError) Error() string { 57 return fmt.Sprintf("%v: %v", v1.ErrorStatus[c.ErrorCode], c.ErrorContext) 58 } 59 60 type File struct { 61 Name string // Basename of the file 62 MIME string // MIME type 63 Digest string // SHA256 of decoded Payload 64 Payload string // base64 encoded file 65 } 66 67 type MDStatusT int 68 69 const ( 70 // All possible MD status codes 71 MDStatusInvalid MDStatusT = 0 // Invalid status, this is a bug 72 MDStatusUnvetted MDStatusT = 1 // Unvetted record 73 MDStatusVetted MDStatusT = 2 // Vetted record 74 MDStatusCensored MDStatusT = 3 // Censored record 75 MDStatusIterationUnvetted MDStatusT = 4 // Unvetted record that has been changed 76 MDStatusArchived MDStatusT = 5 // Vetted record that has been archived 77 MDStatusLast MDStatusT = 6 // Unit test only 78 ) 79 80 var ( 81 // MDStatus converts a status code to a human readable error. 82 MDStatus = map[MDStatusT]string{ 83 MDStatusInvalid: "invalid", 84 MDStatusUnvetted: "unvetted", 85 MDStatusVetted: "vetted", 86 MDStatusCensored: "censored", 87 MDStatusIterationUnvetted: "iteration unvetted", 88 MDStatusArchived: "archived", 89 } 90 ) 91 92 // StateTransitionError indicates an invalid record status transition. 93 type StateTransitionError struct { 94 From MDStatusT 95 To MDStatusT 96 } 97 98 func (s StateTransitionError) Error() string { 99 return fmt.Sprintf("invalid record status transition %v (%v) -> %v (%v)", 100 s.From, MDStatus[s.From], s.To, MDStatus[s.To]) 101 } 102 103 // RecordMetadata is the metadata of a record. 104 const VersionRecordMD = 1 105 106 type RecordMetadata struct { 107 Version uint64 `json:"version"` // Version of the scruture 108 Iteration uint64 `json:"iteration"` // Iteration count of record 109 Status MDStatusT `json:"status"` // Current status of the record 110 Merkle string `json:"merkle"` // Merkle root of all files in record 111 Timestamp int64 `json:"timestamp"` // Last updated 112 Token string `json:"token"` // Record authentication token 113 } 114 115 // MetadataStream describes a single metada stream. The ID determines how and 116 // where it is stored. 117 type MetadataStream struct { 118 ID uint64 // Stream identity 119 Payload string // String encoded metadata 120 } 121 122 // Record is a permanent Record that includes the submitted files, metadata and 123 // internal metadata. 124 type Record struct { 125 RecordMetadata RecordMetadata // Internal metadata 126 Version string // Version of Files 127 Metadata []MetadataStream // User provided metadata 128 Files []File // User provided files 129 } 130 131 // PluginSettings 132 type PluginSetting struct { 133 Key string // Name of setting 134 Value string // Value of setting 135 } 136 137 // Plugin describes a plugin and its settings. 138 type Plugin struct { 139 ID string // Identifier 140 Version string // Version 141 Settings []PluginSetting // Settings 142 } 143 144 type Backend interface { 145 // Create new record 146 New([]MetadataStream, []File) (*RecordMetadata, error) 147 148 // Update unvetted record (token, mdAppend, mdOverwrite, fAdd, fDelete) 149 UpdateUnvettedRecord([]byte, []MetadataStream, []MetadataStream, []File, 150 []string) (*Record, error) 151 152 // Update vetted record (token, mdAppend, mdOverwrite, fAdd, fDelete) 153 UpdateVettedRecord([]byte, []MetadataStream, []MetadataStream, []File, 154 []string) (*Record, error) 155 156 // Update vetted metadata (token, mdAppend, mdOverwrite) 157 UpdateVettedMetadata([]byte, []MetadataStream, 158 []MetadataStream) error 159 160 // Update README.md file at the root of git repo 161 UpdateReadme(string) error 162 163 // Check if an unvetted record exists 164 UnvettedExists([]byte) bool 165 166 // Check if a vetted record exists 167 VettedExists([]byte) bool 168 169 // Get all unvetted record tokens 170 UnvettedTokens() ([][]byte, error) 171 172 // Get all vetted record tokens 173 VettedTokens() ([][]byte, error) 174 175 // Get unvetted record 176 GetUnvetted([]byte) (*Record, error) 177 178 // Get vetted record 179 GetVetted([]byte, string) (*Record, error) 180 181 // Set unvetted record status 182 SetUnvettedStatus([]byte, MDStatusT, []MetadataStream, 183 []MetadataStream) (*Record, error) 184 185 // Set vetted record status 186 SetVettedStatus([]byte, MDStatusT, []MetadataStream, 187 []MetadataStream) (*Record, error) 188 189 // Inventory retrieves various record records. 190 Inventory(uint, uint, uint, bool, bool) ([]Record, []Record, error) 191 192 // Obtain plugin settings 193 GetPlugins() ([]Plugin, error) 194 195 // Plugin pass-through command 196 Plugin(string, string) (string, string, error) // command type, payload, error 197 198 // Close performs cleanup of the backend. 199 Close() 200 }