ValidWorkspaceAppHostname checks if the given host is a valid workspace app hostname based on the provided options. It returns a scheme to force on success. If the hostname is not valid or doesn't match, an empty string is returned. Any error returned is a 500 error. For hosts that match a wildcard
(ctx context.Context, host string, opts ValidWorkspaceAppHostnameOpts)
| 159 | // For hosts that match a wildcard app hostname, the scheme is forced to be the |
| 160 | // corresponding access URL scheme. |
| 161 | func (api *API) ValidWorkspaceAppHostname(ctx context.Context, host string, opts ValidWorkspaceAppHostnameOpts) (string, error) { |
| 162 | if opts.AllowPrimaryAccessURL && (host == api.AccessURL.Hostname() || host == api.AccessURL.Host) { |
| 163 | // Force the redirect URI to have the same scheme as the access URL for |
| 164 | // security purposes. |
| 165 | return api.AccessURL.Scheme, nil |
| 166 | } |
| 167 | |
| 168 | if opts.AllowPrimaryWildcard && api.AppHostnameRegex != nil { |
| 169 | _, ok := appurl.ExecuteHostnamePattern(api.AppHostnameRegex, host) |
| 170 | if ok { |
| 171 | // Force the redirect URI to have the same scheme as the access URL |
| 172 | // for security purposes. |
| 173 | return api.AccessURL.Scheme, nil |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | // Ensure that the redirect URI is a subdomain of api.Hostname and is a |
| 178 | // valid app subdomain. |
| 179 | if opts.AllowProxyAccessURL || opts.AllowProxyWildcard { |
| 180 | // Strip the port for the database query. |
| 181 | host = strings.Split(host, ":")[0] |
| 182 | |
| 183 | // nolint:gocritic // system query |
| 184 | systemCtx := dbauthz.AsSystemRestricted(ctx) |
| 185 | proxy, err := api.Database.GetWorkspaceProxyByHostname(systemCtx, database.GetWorkspaceProxyByHostnameParams{ |
| 186 | Hostname: host, |
| 187 | AllowAccessUrl: opts.AllowProxyAccessURL, |
| 188 | AllowWildcardHostname: opts.AllowProxyWildcard, |
| 189 | }) |
| 190 | if xerrors.Is(err, sql.ErrNoRows) { |
| 191 | return "", nil |
| 192 | } |
| 193 | if err != nil { |
| 194 | return "", xerrors.Errorf("get workspace proxy by hostname %q: %w", host, err) |
| 195 | } |
| 196 | |
| 197 | proxyURL, err := url.Parse(proxy.Url) |
| 198 | if err != nil { |
| 199 | return "", xerrors.Errorf("parse proxy URL %q: %w", proxy.Url, err) |
| 200 | } |
| 201 | |
| 202 | // Force the redirect URI to use the same scheme as the proxy access URL |
| 203 | // for security purposes. |
| 204 | return proxyURL.Scheme, nil |
| 205 | } |
| 206 | |
| 207 | return "", nil |
| 208 | } |
no test coverage detected