github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libpages/config/config.go (about) 1 // Copyright 2017 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package config 6 7 import ( 8 "bytes" 9 "context" 10 "encoding/json" 11 "io" 12 ) 13 14 // DefaultConfigFilename is the default filename for Keybase Pages config file. 15 const DefaultConfigFilename = ".kbp_config" 16 17 // DefaultConfigFilepath is the default path for Keybase Pages config file 18 // under the site root, and is what's used in kbpagesd. 19 const DefaultConfigFilepath = "/.kbp_config" 20 21 // Common includes common fields that should appear in all versions of 22 // configs. 23 type Common struct { 24 // Version specifies the version of the config. 25 Version string `json:"version"` 26 } 27 28 // Version specifies the version of a config. 29 type Version int 30 31 const ( 32 // VersionUnknown defines an unknown config version. 33 VersionUnknown Version = iota 34 // Version1 is version 1. 35 Version1 36 // Version2 is version 2. 37 // 38 // Currently the only difference between V1 and V2 is that V2 uses 39 // sha-based password hash instead of bcrypt in V1. V2 still uses the ACL 40 // definition and checker from V1. 41 Version2 42 ) 43 const ( 44 // VersionUnknownStr is the string representation of VUnknown. 45 VersionUnknownStr string = "unknown" 46 // Version1Str is the string representation of Version1. 47 Version1Str string = "v1" 48 // Version2Str is the string representation of Version2. 49 Version2Str string = "v2" 50 ) 51 52 func (v Version) String() string { 53 switch v { 54 case Version1: 55 return Version1Str 56 case Version2: 57 return Version2Str 58 default: 59 return VersionUnknownStr 60 } 61 62 } 63 64 func parseVersion(s string) (Version, error) { 65 switch s { 66 case Version1Str: 67 return Version1, nil 68 case Version2Str: 69 return Version2, nil 70 default: 71 return VersionUnknown, ErrInvalidVersion{s} 72 } 73 } 74 75 // Config is a collection of methods for getting different configuration 76 // parameters. 77 type Config interface { 78 Version() Version 79 Authenticate(ctx context.Context, username, password string) bool 80 // GetPermissions returns permission info. If username is nil, anonymous 81 // permissions are returned. Otherwise, permissions for *username is 82 // returned. Additionally, "maximum possible permissions" are returned, 83 // which indicates whether a permission (read or list) is possible to be 84 // granted on the path if proper authentication is provided. 85 GetPermissions(path string, username *string) ( 86 read, list bool, 87 possibleRead, possibleList bool, 88 realm string, err error) 89 // GetAccessControlAllowOrigin returns a string that, if non-empty, should 90 // be set as Access-Control-Allow-Origin header. 91 GetAccessControlAllowOrigin(path string) (setting string, err error) 92 93 Encode(w io.Writer, prettify bool) error 94 } 95 96 // ParseConfig parses a config from reader, and initializes internal checker(s) 97 // in the config. 98 func ParseConfig(reader io.Reader) (config Config, err error) { 99 // TODO: make a better decoder to avoid having a buffer here and decoding 100 // twice. 101 buf := &bytes.Buffer{} 102 var common Common 103 err = json.NewDecoder(io.TeeReader(reader, buf)).Decode(&common) 104 if err != nil { 105 return nil, err 106 } 107 v, err := parseVersion(common.Version) 108 if err != nil { 109 return nil, err 110 } 111 switch v { 112 case Version1: 113 var v1 V1 114 err = json.NewDecoder(buf).Decode(&v1) 115 if err != nil { 116 return nil, err 117 } 118 return &v1, (&v1).EnsureInit() 119 default: 120 return nil, ErrInvalidVersion{} 121 } 122 }