github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/asserts/account.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package asserts 21 22 import ( 23 "fmt" 24 "regexp" 25 "time" 26 ) 27 28 var ( 29 // account ids look like snap-ids or a nice identifier 30 validAccountID = regexp.MustCompile("^(?:[a-z0-9A-Z]{32}|[-a-z0-9]{2,28})$") 31 ) 32 33 // Account holds an account assertion, which ties a name for an account 34 // to its identifier and provides the authority's confidence in the name's validity. 35 type Account struct { 36 assertionBase 37 validation string 38 timestamp time.Time 39 } 40 41 // AccountID returns the account-id of the account. 42 func (acc *Account) AccountID() string { 43 return acc.HeaderString("account-id") 44 } 45 46 // Username returns the user name for the account. 47 func (acc *Account) Username() string { 48 return acc.HeaderString("username") 49 } 50 51 // DisplayName returns the human-friendly name for the account. 52 func (acc *Account) DisplayName() string { 53 return acc.HeaderString("display-name") 54 } 55 56 // Validation returns the level of confidence of the authority in the 57 // account's identity, expected to be "unproven" or "verified", and 58 // for forward compatibility any value != "unproven" can be considered 59 // at least "verified". 60 func (acc *Account) Validation() string { 61 return acc.validation 62 } 63 64 // Timestamp returns the time when the account was issued. 65 func (acc *Account) Timestamp() time.Time { 66 return acc.timestamp 67 } 68 69 // Implement further consistency checks. 70 func (acc *Account) checkConsistency(db RODatabase, acck *AccountKey) error { 71 if !db.IsTrustedAccount(acc.AuthorityID()) { 72 return fmt.Errorf("account assertion for %q is not signed by a directly trusted authority: %s", acc.AccountID(), acc.AuthorityID()) 73 } 74 return nil 75 } 76 77 // sanity 78 var _ consistencyChecker = (*Account)(nil) 79 80 func assembleAccount(assert assertionBase) (Assertion, error) { 81 _, err := checkNotEmptyString(assert.headers, "display-name") 82 if err != nil { 83 return nil, err 84 } 85 86 validation, err := checkNotEmptyString(assert.headers, "validation") 87 if err != nil { 88 return nil, err 89 } 90 // backward compatibility with the hard-coded trusted account 91 // assertions 92 // TODO: generate revision 1 of them with validation 93 // s/certified/verified/ 94 if validation == "certified" { 95 validation = "verified" 96 } 97 98 timestamp, err := checkRFC3339Date(assert.headers, "timestamp") 99 if err != nil { 100 return nil, err 101 } 102 103 _, err = checkOptionalString(assert.headers, "username") 104 if err != nil { 105 return nil, err 106 } 107 108 return &Account{ 109 assertionBase: assert, 110 validation: validation, 111 timestamp: timestamp, 112 }, nil 113 }