go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/oauth/state.go (about) 1 /* 2 3 Copyright (c) 2023 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package oauth 9 10 import ( 11 "bytes" 12 "encoding/base64" 13 "encoding/gob" 14 ) 15 16 // State is the oauth state. 17 type State struct { 18 // Token is a plaintext random token. 19 Token string 20 // SecureToken is the hashed version of the token. 21 // If a key is set, it validates that our app created the oauth state. 22 SecureToken string 23 // RedirectURI is the redirect uri. 24 RedirectURI string 25 // Extra includes other state you might need to encode. 26 Extra map[string]interface{} 27 } 28 29 // DeserializeState deserializes the oauth state. 30 func DeserializeState(raw string) (state State, err error) { 31 var corpus []byte 32 corpus, err = base64.RawURLEncoding.DecodeString(raw) 33 if err != nil { 34 return 35 } 36 buffer := bytes.NewBuffer(corpus) 37 err = gob.NewDecoder(buffer).Decode(&state) 38 return 39 } 40 41 // MustSerializeState serializes a state value but panics if there is an error. 42 func MustSerializeState(state State) string { 43 output, err := SerializeState(state) 44 if err != nil { 45 panic(err) 46 } 47 return output 48 } 49 50 // SerializeState serializes the oauth state. 51 func SerializeState(state State) (output string, err error) { 52 buffer := new(bytes.Buffer) 53 err = gob.NewEncoder(buffer).Encode(state) 54 if err != nil { 55 return 56 } 57 output = base64.RawURLEncoding.EncodeToString(buffer.Bytes()) 58 return 59 } 60 61 // StateOption is an option for state objects 62 type StateOption func(*State) 63 64 // OptStateSecureToken sets the secure token on the state. 65 func OptStateSecureToken(secureToken string) StateOption { 66 return func(s *State) { 67 s.SecureToken = secureToken 68 } 69 } 70 71 // OptStateRedirectURI sets the redirect uri on the stae. 72 func OptStateRedirectURI(redirectURI string) StateOption { 73 return func(s *State) { 74 s.RedirectURI = redirectURI 75 } 76 } 77 78 // OptStateExtra sets the redirect uri on the stae. 79 func OptStateExtra(key string, value interface{}) StateOption { 80 return func(s *State) { 81 if s.Extra == nil { 82 s.Extra = make(map[string]interface{}) 83 } 84 s.Extra[key] = value 85 } 86 }