github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/context_Auth.go (about) 1 // Copyright 2017-present Kirill Danshin and Gramework contributors 2 // Copyright 2019-present Highload LTD (UK CN: 11893420) 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 11 package gramework 12 13 import ( 14 "bytes" 15 "encoding/base64" 16 "errors" 17 ) 18 19 var ( 20 authHeaderName = []byte("Authorization") 21 authSplitter = []byte(":") 22 errInvalidAuth = errors.New("invalid auth request") 23 ) 24 25 // GetPass lazy triggers parser and returns 26 // password or an error. Error will be persistent 27 // for current context 28 // 29 // Common typos: GetPassword 30 func (a *Auth) GetPass() (string, error) { 31 // yep, we copying the code, but 32 // we get one instead of two jumps 33 if !a.parsed { 34 a.parse() 35 } 36 37 return a.pass, a.err 38 } 39 40 // GetLogin lazy triggers parser and returns 41 // login or an error. Error will be persistent 42 // for current context 43 // 44 // Common typos: GetUser, GetUsername 45 func (a *Auth) GetLogin() (string, error) { 46 if !a.parsed { 47 a.parse() 48 } 49 50 return a.login, a.err 51 } 52 53 func (a *Auth) parse() { 54 if a.err != nil { 55 return // parsing already failed 56 } 57 auth := a.ctx.Request.Header.PeekBytes(authHeaderName) 58 if len(auth) < 7 { 59 a.err = errInvalidAuth 60 return 61 } 62 decoded, err := base64.StdEncoding.DecodeString(BytesToString(auth[6:])) 63 if err != nil { 64 a.err = err 65 return 66 } 67 68 splitted := bytes.Split(decoded, authSplitter) 69 70 if len(splitted) != 2 { 71 a.err = errInvalidAuth 72 return 73 } 74 75 a.login, a.pass = string(splitted[0]), string(splitted[1]) 76 } 77 78 // Auth returns struct for simple basic auth handling 79 // 80 // useful to develop e.g. stage environment login, 81 // where high security is not required 82 func (ctx *Context) Auth() *Auth { 83 if ctx.auth == nil { 84 ctx.auth = &Auth{ 85 ctx: ctx, 86 } 87 } 88 return ctx.auth 89 }