/* Copyright 2020 The Vouch Proxy Authors. Use of this source code is governed by The MIT License (MIT) that can be found in the LICENSE file. Software distributed under The MIT License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ package indieauth import ( "bytes" "encoding/json" "golang.org/x/oauth2" "io/ioutil" "mime/multipart" "net/http" "github.com/vouch/vouch-proxy/pkg/cfg" "github.com/vouch/vouch-proxy/pkg/providers/common" "github.com/vouch/vouch-proxy/pkg/structs" "go.uber.org/zap" ) // Provider provider specific functions type Provider struct{} var log *zap.SugaredLogger // Configure see main.go configure() func (Provider) Configure() { log = cfg.Logging.Logger } // GetUserInfo provider specific call to get userinfomation func (Provider) GetUserInfo(r *http.Request, user *structs.User, customClaims *structs.CustomClaims, ptokens *structs.PTokens, opts ...oauth2.AuthCodeOption) (rerr error) { // indieauth sends the "me" setting in json back to the callback, so just pluck it from the callback code := r.URL.Query().Get("code") log.Errorf("ptoken.AccessToken: %s", code) var b bytes.Buffer w := multipart.NewWriter(&b) // v.Set("code", code) fw, err := w.CreateFormField("code") if err != nil { return err } if _, err = fw.Write([]byte(code)); err != nil { return err } // v.Set("redirect_uri", cfg.GenOAuth.RedirectURL) if fw, err = w.CreateFormField("redirect_uri"); err != nil { return err } if _, err = fw.Write([]byte(cfg.GenOAuth.RedirectURL)); err != nil { return err } // v.Set("client_id", cfg.GenOAuth.ClientID) if fw, err = w.CreateFormField("client_id"); err != nil { return err } if _, err = fw.Write([]byte(cfg.GenOAuth.ClientID)); err != nil { return err } if err = w.Close(); err != nil { log.Error("error closing writer.") } req, err := http.NewRequest("POST", cfg.GenOAuth.AuthURL, &b) if err != nil { return err } req.Header.Set("Content-Type", w.FormDataContentType()) req.Header.Set("Accept", "application/json") // v := url.Values{} // userinfo, err := client.PostForm(cfg.GenOAuth.UserInfoURL, v) client := &http.Client{} userinfo, err := client.Do(req) if err != nil { // http.Error(w, err.Error(), http.StatusBadRequest) return err } defer func() { if err := userinfo.Body.Close(); err != nil { rerr = err } }() data, _ := ioutil.ReadAll(userinfo.Body) log.Infof("indieauth userinfo body: %s", string(data)) if err = common.MapClaims(data, customClaims); err != nil { log.Error(err) return err } iaUser := structs.IndieAuthUser{} if err = json.Unmarshal(data, &iaUser); err != nil { log.Error(err) return err } iaUser.PrepareUserData() user.Username = iaUser.Username log.Debug(user) return nil }