github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/auth/auth.go (about) 1 // Copyright 2020 Asim Aslam 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Original source: github.com/micro/go-micro/v3/auth/auth.go 16 17 package auth 18 19 import ( 20 "context" 21 "errors" 22 "time" 23 ) 24 25 var ( 26 // DefaultAuth implementation 27 DefaultAuth Auth 28 // ErrInvalidToken is when the token provided is not valid 29 ErrInvalidToken = errors.New("invalid token provided") 30 // ErrForbidden is when a user does not have the necessary scope to access a resource 31 ErrForbidden = errors.New("resource forbidden") 32 ) 33 34 const ( 35 // ScopePublic is the scope applied to a rule to allow access to the public 36 ScopePublic = "" 37 // ScopeAccount is the scope applied to a rule to limit to users with any valid account 38 ScopeAccount = "*" 39 // ScopeAnyNamespaceAccount is the scope applied to a rule to limit to users with any valid account regardless of issuer 40 ScopeAnyNamespaceAccount = "+" 41 ) 42 43 // Account provided by an auth provider 44 type Account struct { 45 // ID of the account e.g. UUID. Should not change 46 ID string `json:"id"` 47 // Type of the account, e.g. api, client, service, user 48 Type string `json:"type"` 49 // Issuer of the account e.g micro 50 Issuer string `json:"issuer"` 51 // Any other associated metadata 52 Metadata map[string]string `json:"metadata"` 53 // Scopes the account has access to 54 Scopes []string `json:"scopes"` 55 // Secret for the account, e.g. the password 56 Secret string `json:"secret"` 57 // Name of the account. User friendly name that might change e.g. a username or email 58 Name string `json:"name"` 59 } 60 61 // AccountToken can be short or long lived 62 type AccountToken struct { 63 // The token to be used for accessing resources 64 AccessToken string `json:"access_token"` 65 // RefreshToken to be used to generate a new token 66 RefreshToken string `json:"refresh_token"` 67 // Time of token creation 68 Created time.Time `json:"created"` 69 // Time of token expiry 70 Expiry time.Time `json:"expiry"` 71 } 72 73 // Expired returns a boolean indicating if the token needs to be refreshed 74 func (t *AccountToken) Expired() bool { 75 return t.Expiry.Unix() < time.Now().Unix() 76 } 77 78 // Resource is an entity such as a user or 79 type Resource struct { 80 // Name of the resource, e.g. go.micro.service.notes 81 Name string `json:"name"` 82 // Type of resource, e.g. service 83 Type string `json:"type"` 84 // Endpoint resource e.g NotesService.Create 85 Endpoint string `json:"endpoint"` 86 } 87 88 // Access defines the type of access a rule grants 89 type Access int 90 91 const ( 92 // AccessGranted to a resource 93 AccessGranted Access = iota 94 // AccessDenied to a resource 95 AccessDenied 96 ) 97 98 // Rule is used to verify access to a resource 99 type Rule struct { 100 // ID of the rule, e.g. "public" 101 ID string 102 // Scope the rule requires, a blank scope indicates open to the public and * indicates the rule 103 // applies to any valid account 104 Scope string 105 // Resource the rule applies to 106 Resource *Resource 107 // Access determines if the rule grants or denies access to the resource 108 Access Access 109 // Priority the rule should take when verifying a request, the higher the value the sooner the 110 // rule will be applied 111 Priority int32 112 } 113 114 // Auth provides authentication and authorization 115 type Auth interface { 116 // Init the auth 117 Init(opts ...Option) 118 // Options set for auth 119 Options() Options 120 // Generate a new account 121 Generate(id string, opts ...GenerateOption) (*Account, error) 122 // Verify an account has access to a resource using the rules 123 Verify(acc *Account, res *Resource, opts ...VerifyOption) error 124 // Inspect a token 125 Inspect(token string) (*Account, error) 126 // Token generated using refresh token or credentials 127 Token(opts ...TokenOption) (*AccountToken, error) 128 // Grant access to a resource 129 Grant(rule *Rule) error 130 // Revoke access to a resource 131 Revoke(rule *Rule) error 132 // Rules returns all the rules used to verify requests 133 Rules(...RulesOption) ([]*Rule, error) 134 // String returns the name of the implementation 135 String() string 136 } 137 138 // Generate a new account 139 func Generate(id string, opts ...GenerateOption) (*Account, error) { 140 return DefaultAuth.Generate(id, opts...) 141 } 142 143 // Verify an account has access to a resource using the rules 144 func Verify(acc *Account, res *Resource, opts ...VerifyOption) error { 145 return DefaultAuth.Verify(acc, res, opts...) 146 } 147 148 // Inspect a token 149 func Inspect(token string) (*Account, error) { 150 return DefaultAuth.Inspect(token) 151 } 152 153 // Token generated using refresh token or credentials 154 func Token(opts ...TokenOption) (*AccountToken, error) { 155 return DefaultAuth.Token(opts...) 156 } 157 158 // Grant access to a resource 159 func Grant(rule *Rule) error { 160 return DefaultAuth.Grant(rule) 161 } 162 163 // Revoke access to a resource 164 func Revoke(rule *Rule) error { 165 return DefaultAuth.Revoke(rule) 166 } 167 168 // Rules returns all the rules used to verify requests 169 func Rules(...RulesOption) ([]*Rule, error) { 170 return DefaultAuth.Rules() 171 } 172 173 type accountKey struct{} 174 175 // AccountFromContext gets the account from the context, which 176 // is set by the auth wrapper at the start of a call. If the account 177 // is not set, a nil account will be returned. The error is only returned 178 // when there was a problem retrieving an account 179 func AccountFromContext(ctx context.Context) (*Account, bool) { 180 acc, ok := ctx.Value(accountKey{}).(*Account) 181 return acc, ok 182 } 183 184 // ContextWithAccount sets the account in the context 185 func ContextWithAccount(ctx context.Context, account *Account) context.Context { 186 return context.WithValue(ctx, accountKey{}, account) 187 }