package oauth import ( "cs-bridge/internal/auth" "cs-bridge/internal/config" "cs-bridge/pkg/httpclient" "encoding/json" "fmt" "net/url" "time" ) type Gitea struct { cfg config.Provider redirectURI string } // Name implements [Provider]. func (g Gitea) Name() string { return "gitea" } // AuthURL implements [Provider]. func (g Gitea) AuthURL(state string) (string, error) { u, _ := url.Parse(g.cfg.BaseURL + g.cfg.AuthorizeURL) q := u.Query() q.Set("client_id", g.cfg.ClientID) q.Set("redirect_uri", g.redirectURI) q.Set("response_type", "code") q.Set("scope", "read:user") q.Set("state", state) u.RawQuery = q.Encode() return u.String(), nil } // Exchange implements [Provider]. func (g Gitea) Exchange(code string) (string, error) { resp, err := httpclient.Default.R(). SetHeader("Accept", "application/json"). SetFormData(map[string]string{ "client_id": g.cfg.ClientID, "client_secret": g.cfg.ClientSecret, "code": code, "grant_type": "authorization_code", "redirect_uri": g.redirectURI, }). Post(fmt.Sprintf("%s%s", g.cfg.BaseURL, g.cfg.TokenURL)) if err != nil { return "", err } var out struct { AccessToken string `json:"access_token"` TokenType string `json:"token_type"` ExpiresIn string `json:"expires_in"` RefreshToken string `json:"refresh_token"` } json.NewDecoder(resp.Body).Decode(&out) return out.AccessToken, nil } // UserInfo implements [Provider]. func (g Gitea) UserInfo(token string) (auth.Identify, error) { resp, err := httpclient.Default.R(). SetHeader("Authorization", fmt.Sprintf("bearer %s", token)). Get(fmt.Sprintf("%s%s", g.cfg.BaseURL, g.cfg.UserURL)) if err != nil { return auth.Identify{}, err } var raw raw json.NewDecoder(resp.Body).Decode(&raw) return auth.Identify{ Provider: g.Name(), UserId: fmt.Sprint(raw.ID), Username: raw.Login, Avatar: raw.AvatarURL, }, nil } func NewGitea(cfg config.Provider, redirectURI string) Gitea { return Gitea{ cfg: cfg, redirectURI: redirectURI, } } type raw struct { ID int `json:"id"` Login string `json:"login"` LoginName string `json:"login_name"` SourceID int `json:"source_id"` FullName string `json:"full_name"` Email string `json:"email"` AvatarURL string `json:"avatar_url"` HTMLURL string `json:"html_url"` Language string `json:"language"` IsAdmin bool `json:"is_admin"` LastLogin time.Time `json:"last_login"` Created time.Time `json:"created"` Restricted bool `json:"restricted"` Active bool `json:"active"` ProhibitLogin bool `json:"prohibit_login"` Location string `json:"location"` Website string `json:"website"` Description string `json:"description"` Visibility string `json:"visibility"` FollowersCount int `json:"followers_count"` FollowingCount int `json:"following_count"` StarredReposCount int `json:"starred_repos_count"` Username string `json:"username"` }