ConvertConfig converts the SDK configuration entry format to the parsed and ready-to-consume in coderd provider type.
(instrument *promoauth.Factory, entries []codersdk.ExternalAuthConfig, accessURL *url.URL)
| 814 | // ConvertConfig converts the SDK configuration entry format |
| 815 | // to the parsed and ready-to-consume in coderd provider type. |
| 816 | func ConvertConfig(instrument *promoauth.Factory, entries []codersdk.ExternalAuthConfig, accessURL *url.URL) ([]*Config, error) { |
| 817 | ids := map[string]struct{}{} |
| 818 | configs := []*Config{} |
| 819 | for _, entry := range entries { |
| 820 | // Applies defaults to the config entry. |
| 821 | // This allows users to very simply state that they type is "GitHub", |
| 822 | // apply their client secret and ID, and have the UI appear nicely. |
| 823 | applyDefaultsToConfig(&entry) |
| 824 | |
| 825 | valid := codersdk.NameValid(entry.ID) |
| 826 | if valid != nil { |
| 827 | return nil, xerrors.Errorf("external auth provider %q doesn't have a valid id: %w", entry.ID, valid) |
| 828 | } |
| 829 | if entry.ClientID == "" { |
| 830 | return nil, xerrors.Errorf("%q external auth provider: client_id must be provided", entry.ID) |
| 831 | } |
| 832 | |
| 833 | _, exists := ids[entry.ID] |
| 834 | if exists { |
| 835 | if entry.ID == entry.Type { |
| 836 | return nil, xerrors.Errorf("multiple %s external auth providers provided. you must specify a unique id for each", entry.Type) |
| 837 | } |
| 838 | return nil, xerrors.Errorf("multiple external auth providers exist with the id %q. specify a unique id for each", entry.ID) |
| 839 | } |
| 840 | ids[entry.ID] = struct{}{} |
| 841 | |
| 842 | authRedirect, err := accessURL.Parse(fmt.Sprintf("/external-auth/%s/callback", entry.ID)) |
| 843 | if err != nil { |
| 844 | return nil, xerrors.Errorf("parse external auth callback url: %w", err) |
| 845 | } |
| 846 | |
| 847 | var regex *regexp.Regexp |
| 848 | if entry.Regex != "" { |
| 849 | regex, err = regexp.Compile(entry.Regex) |
| 850 | if err != nil { |
| 851 | return nil, xerrors.Errorf("compile regex for external auth provider %q: %w", entry.ID, entry.Regex) |
| 852 | } |
| 853 | } |
| 854 | |
| 855 | oc := &oauth2.Config{ |
| 856 | ClientID: entry.ClientID, |
| 857 | ClientSecret: entry.ClientSecret, |
| 858 | Endpoint: oauth2.Endpoint{ |
| 859 | AuthURL: entry.AuthURL, |
| 860 | TokenURL: entry.TokenURL, |
| 861 | }, |
| 862 | RedirectURL: authRedirect.String(), |
| 863 | Scopes: entry.Scopes, |
| 864 | } |
| 865 | |
| 866 | var oauthConfig promoauth.OAuth2Config = oc |
| 867 | // Azure DevOps uses JWT token authentication! |
| 868 | if entry.Type == string(codersdk.EnhancedExternalAuthProviderAzureDevops) { |
| 869 | oauthConfig = &jwtConfig{oc} |
| 870 | } |
| 871 | if entry.Type == string(codersdk.EnhancedExternalAuthProviderAzureDevopsEntra) { |
| 872 | oauthConfig = &entraV1Oauth{oc} |
| 873 | } |