package main import ( "context" "encoding/json" "errors" "fmt" "io" "net/http" "net/url" "strings" "git.cin.su/m/Assistant/contracts/identity" ) var ( errCreatorSessionDenied = errors.New("creator session denied") errIdentityUnavailable = errors.New("identity service unavailable") ) type creatorIdentityClient struct { baseURL *url.URL client *http.Client } func newCreatorIdentityClient(rawURL string, client *http.Client) (creatorIdentityClient, error) { baseURL, err := url.Parse(rawURL) if err != nil || baseURL.Scheme == "" || baseURL.Host == "" { return creatorIdentityClient{}, fmt.Errorf("invalid Core Runtime URL") } return creatorIdentityClient{baseURL: baseURL, client: client}, nil } func (c creatorIdentityClient) Session(ctx context.Context, authorization string) (identity.CreatorSession, error) { if !strings.HasPrefix(authorization, "Bearer ") || len(strings.TrimPrefix(authorization, "Bearer ")) == 0 { return identity.CreatorSession{}, errCreatorSessionDenied } target := *c.baseURL target.Path = "/v1/creator/sessions/current" target.RawQuery = "" request, err := http.NewRequestWithContext(ctx, http.MethodGet, target.String(), nil) if err != nil { return identity.CreatorSession{}, fmt.Errorf("%w: build request", errIdentityUnavailable) } request.Header.Set("Authorization", authorization) response, err := c.client.Do(request) if err != nil { return identity.CreatorSession{}, fmt.Errorf("%w: %v", errIdentityUnavailable, err) } defer response.Body.Close() if response.StatusCode == http.StatusUnauthorized { return identity.CreatorSession{}, errCreatorSessionDenied } if response.StatusCode != http.StatusOK { return identity.CreatorSession{}, fmt.Errorf("%w: status %d", errIdentityUnavailable, response.StatusCode) } var session identity.CreatorSession if err := json.NewDecoder(io.LimitReader(response.Body, 16<<10)).Decode(&session); err != nil { return identity.CreatorSession{}, fmt.Errorf("%w: invalid response", errIdentityUnavailable) } if session.ActorID == "" || session.PrincipalID == "" { return identity.CreatorSession{}, fmt.Errorf("%w: incomplete session", errIdentityUnavailable) } return session, nil }