Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Config Refactor Round 2. #2771

Merged
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
bf67175
Config Refactor Round 2.
nharper285 Jan 24, 2023
4b1a64e
Adding docs.
nharper285 Jan 24, 2023
fc1a86c
Fix file formatting.
nharper285 Jan 25, 2023
b8705fc
Removing.
nharper285 Jan 25, 2023
153f0b9
fixing imports.
nharper285 Jan 25, 2023
ec4a2fc
Removing.
nharper285 Jan 25, 2023
16b82e8
Fixing cli access token retrieval.
nharper285 Jan 25, 2023
ae9acaa
Fixing authority check.
nharper285 Jan 25, 2023
7d6c864
Merge branch 'main' into user/noharper/config-endpoint-update-2
nharper285 Jan 25, 2023
ae9b57f
Small edits.
nharper285 Jan 25, 2023
fb914dc
Merge branch 'user/noharper/config-endpoint-update-2' of https://gith…
nharper285 Jan 25, 2023
e7b9c5a
Removing duplicate.
nharper285 Jan 25, 2023
6073689
Adding uuid check.
nharper285 Jan 25, 2023
733840c
Possible to override with existing params.
nharper285 Jan 25, 2023
72669a6
Allowing flags to override storage.
nharper285 Jan 26, 2023
22f40fc
Trying to fix config params.?
nharper285 Jan 26, 2023
a83257e
Fixing.
nharper285 Jan 26, 2023
a4eb26d
Set endpoint params via app function.
nharper285 Jan 26, 2023
2e2ecc2
Checking changes to params.
nharper285 Jan 26, 2023
cd4f408
Make tenant_domain default.
nharper285 Jan 26, 2023
1e63be9
Merge branch 'main' into user/noharper/config-endpoint-update-2
nharper285 Jan 26, 2023
ffe8146
Remove endoint params from models.
nharper285 Jan 26, 2023
a5a6a54
UPdating docs.
nharper285 Jan 26, 2023
b5c3a74
Setting
nharper285 Jan 26, 2023
f184bc9
Removing hardcoded values.
nharper285 Jan 26, 2023
efe3a06
Typo.
nharper285 Jan 26, 2023
081b454
Removing endpoint upload.
nharper285 Jan 26, 2023
5fa1abc
Typo.
nharper285 Jan 26, 2023
dbe3f67
Fixing typos.
nharper285 Jan 26, 2023
794be7a
Fix error message about aad tenant.
nharper285 Jan 30, 2023
3b07e54
Merge branch 'main' into user/noharper/config-endpoint-update-2
nharper285 Jan 30, 2023
d78ac48
Responding to comments.
nharper285 Jan 30, 2023
7ac405c
Merge branch 'user/noharper/config-endpoint-update-2' of https://gith…
nharper285 Jan 30, 2023
c867a1c
Merge branch 'main' into user/noharper/config-endpoint-update-2
nharper285 Jan 31, 2023
ab844c8
Update src/ApiService/ApiService/UserCredentials.cs
nharper285 Jan 31, 2023
e5d1e2c
Merge branch 'main' into user/noharper/config-endpoint-update-2
nharper285 Jan 31, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/ApiService/ApiService/Functions/Config.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;

namespace Microsoft.OneFuzz.Service.Functions;

public class Config {
private readonly ILogTracer _log;
private readonly IOnefuzzContext _context;

public Config(ILogTracer log, IOnefuzzContext context) {
_log = log;
_context = context;
}

[Function("Config")]
public Async.Task<HttpResponseData> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "GET", Route = "config")] HttpRequestData req) {
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
return Get(req);
}
public async Async.Task<HttpResponseData> Get(HttpRequestData req) {
_log.Info($"getting endpoint config parameters");

var endpointParams = new ConfigResponse(
Authority: _context.ServiceConfiguration.Authority,
ClientId: _context.ServiceConfiguration.CliAppId,
TenantDomain: _context.ServiceConfiguration.TenantDomain);

var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteAsJsonAsync(endpointParams);

return response;
}
}
6 changes: 6 additions & 0 deletions src/ApiService/ApiService/OneFuzzTypes/Responses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,12 @@ public static ScalesetResponse ForScaleset(Scaleset s, bool includeAuth)
Nodes: null);
}

public record ConfigResponse(
string? Authority,
string? ClientId,
string? TenantDomain
) : BaseResponse();

public class BaseResponseConverter : JsonConverter<BaseResponse> {
public override BaseResponse? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
return null;
Expand Down
8 changes: 6 additions & 2 deletions src/ApiService/ApiService/ServiceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public interface IServiceConfig {

public string? DiagnosticsAzureBlobContainerSasUrl { get; }
public string? DiagnosticsAzureBlobRetentionDays { get; }

public string? CliAppId { get; }
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
public string? Authority { get; }
public string? TenantDomain { get; }
public string? MultiTenantDomain { get; }
public ResourceIdentifier? OneFuzzDataStorage { get; }
public ResourceIdentifier? OneFuzzFuncStorage { get; }
Expand Down Expand Up @@ -97,7 +99,9 @@ public ServiceConfiguration() {

public string? DiagnosticsAzureBlobContainerSasUrl { get => GetEnv("DIAGNOSTICS_AZUREBLOBCONTAINERSASURL"); }
public string? DiagnosticsAzureBlobRetentionDays { get => GetEnv("DIAGNOSTICS_AZUREBLOBRETENTIONINDAYS"); }

public string? CliAppId { get => GetEnv("CLI_APP_ID"); }
public string? Authority { get => GetEnv("AUTHORITY"); }
public string? TenantDomain { get => GetEnv("TENANT_DOMAIN"); }
public string? MultiTenantDomain { get => GetEnv("MULTI_TENANT_DOMAIN"); }

public ResourceIdentifier? OneFuzzDataStorage {
Expand Down
2 changes: 1 addition & 1 deletion src/ApiService/ApiService/onefuzzlib/ConfigOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private sealed record InstanceConfigCacheKey();
private static readonly InstanceConfigCacheKey _key = new(); // singleton key
public Task<InstanceConfig> Fetch()
=> _cache.GetOrCreateAsync(_key, async entry => {
entry = entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(10)); // cached for 10 minutes
entry = entry.SetAbsoluteExpiration(TimeSpan.FromMinutes(1)); // cached for 1 minute
stishkin marked this conversation as resolved.
Show resolved Hide resolved
var key = _context.ServiceConfiguration.OneFuzzInstanceName ?? throw new Exception("Environment variable ONEFUZZ_INSTANCE_NAME is not set");
return await GetEntityAsync(key, key);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public TestServiceConfiguration(string tablePrefix) {

public string? OneFuzzTelemetry => "TestOneFuzzTelemetry";

public string? CliAppId => "TestGuid";

public string? Authority => "TestAuthority";

public string? TenantDomain => "TestDomain";
public string? MultiTenantDomain => null;

public string? OneFuzzInstanceName => "UnitTestInstance";
Expand Down
49 changes: 46 additions & 3 deletions src/cli/onefuzz/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@
UUID_EXPANSION = TypeVar("UUID_EXPANSION", UUID, str)

DEFAULT = BackendConfig(
authority="https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47",
client_id="72f1562a-8c0c-41ea-beb9-fa2b71c80134",
authority="",
client_id="",
tenant_domain="",
)

# This was generated randomly and should be preserved moving forwards
Expand Down Expand Up @@ -122,6 +123,10 @@ def _req_model(
as_params: bool = False,
alternate_endpoint: Optional[str] = None,
) -> A:

# Retrieve Auth Parameters
self._req_config_params()

response = self._req_base(
method,
data=data,
Expand Down Expand Up @@ -153,6 +158,42 @@ def _req_model_list(

return [model.parse_obj(x) for x in response]

def _req_config_params(
self,
) -> None:

endpoint_params = responses.Config(
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
authority="",
client_id="",
tenant_domain="",
)

if self.onefuzz._backend.config.endpoint is not None:
nharper285 marked this conversation as resolved.
Show resolved Hide resolved

endpoint = self.onefuzz._backend.config.endpoint

response = self.onefuzz._backend.session.request(
"GET", endpoint + "/api/config"
)

logging.debug(response.json())
endpoint_params = responses.Config.parse_obj(response.json())

logging.debug(self.onefuzz._backend.config.authority)
# Will override values in storage w/ provided values for SP use
if self.onefuzz._backend.config.client_id == "":
self.onefuzz._backend.config.client_id = endpoint_params.client_id
if self.onefuzz._backend.config.authority == "":
self.onefuzz._backend.config.authority = endpoint_params.authority
if self.onefuzz._backend.config.tenant_domain == "":
self.onefuzz._backend.config.tenant_domain = (
endpoint_params.tenant_domain
)

self.onefuzz._backend.save_config()
else:
raise Exception("Endpoint Not Configured")

def _disambiguate(
self,
name: str,
Expand Down Expand Up @@ -1862,7 +1903,9 @@ def config(
self.logger.debug("set config")

if reset:
self._backend.config = BackendConfig(authority="", client_id="")
self._backend.config = BackendConfig(
authority="", client_id="", tenant_domain=""
)

if endpoint is not None:
# The normal path for calling the API always uses the oauth2 workflow,
Expand Down
5 changes: 3 additions & 2 deletions src/cli/onefuzz/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class BackendConfig(BaseModel):
client_id: str
endpoint: Optional[str]
features: Set[str] = Field(default_factory=set)
tenant_domain: Optional[str]
tenant_domain: str


class Backend:
Expand Down Expand Up @@ -181,7 +181,7 @@ def get_access_token(self) -> Any:
if not self.config.endpoint:
raise Exception("endpoint not configured")

if self.config.tenant_domain:
if "common" in self.config.authority:
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
endpoint = urlparse(self.config.endpoint).netloc.split(".")[0]
scopes = [
f"api://{self.config.tenant_domain}/{endpoint}/.default",
Expand Down Expand Up @@ -321,6 +321,7 @@ def request(
if not endpoint:
raise Exception("endpoint not configured")

LOGGER.info(self.headers)
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
url = endpoint + "/api/" + path
headers = self.headers()
json_data = serialize(json_data)
Expand Down
6 changes: 6 additions & 0 deletions src/deployment/azuredeploy.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ param clientSecret string
param signedExpiry string
param app_func_issuer string
param app_func_audiences array
param cli_app_id string
param authority string
param tenant_domain string
param multi_tenant_domain string
param enable_remote_debugging bool = false
param enable_profiler bool = false
Expand Down Expand Up @@ -239,6 +242,9 @@ module functionSettings 'bicep-templates/function-settings.bicep' = {
fuzz_storage_resource_id: storage.outputs.FuzzId
keyvault_name: keyVaultName
monitor_account_name: operationalInsights.outputs.monitorAccountName
cli_app_id: cli_app_id
authority: authority
tenant_domain: tenant_domain
multi_tenant_domain: multi_tenant_domain
enable_profiler: enable_profiler
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
Expand Down
10 changes: 8 additions & 2 deletions src/deployment/bicep-templates/function-settings.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ param app_insights_key string
@secure()
param func_sas_url string

param cli_app_id string
param authority string
param tenant_domain string
param multi_tenant_domain string

@secure()
Expand Down Expand Up @@ -37,7 +40,7 @@ resource function 'Microsoft.Web/sites@2021-02-01' existing = {
}

var enable_profilers = enable_profiler ? {
APPINSIGHTS_PROFILERFEATURE_VERSION : '1.0.0'
APPINSIGHTS_PROFILERFEATURE_VERSION: '1.0.0'
DiagnosticServices_EXTENSION_VERSION: '~3'
} : {}

Expand All @@ -52,6 +55,9 @@ resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
APPINSIGHTS_APPID: app_insights_app_id
ONEFUZZ_TELEMETRY: telemetry
AzureWebJobsStorage: func_sas_url
CLI_APP_ID: cli_app_id
AUTHORITY: authority
TENANT_DOMAIN: tenant_domain
MULTI_TENANT_DOMAIN: multi_tenant_domain
AzureWebJobsDisableHomepage: 'true'
AzureSignalRConnectionString: signal_r_connection_string
Expand All @@ -66,5 +72,5 @@ resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
ONEFUZZ_KEYVAULT: keyvault_name
ONEFUZZ_OWNER: owner
ONEFUZZ_CLIENT_SECRET: client_secret
}, enable_profilers)
}, enable_profilers)
}
14 changes: 7 additions & 7 deletions src/deployment/bicep-templates/function.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ param diagnostics_log_level string
param log_retention int
param linux_fx_version string


var siteconfig = (use_windows) ? {
} : {
linuxFxVersion: linux_fx_version
Expand Down Expand Up @@ -57,24 +56,25 @@ resource function 'Microsoft.Web/sites@2021-03-01' = {
type: 'SystemAssigned'
}
properties: union({
siteConfig: union(siteconfig, commonSiteConfig)
httpsOnly: true
serverFarmId: server_farm_id
clientAffinityEnabled: true
}, extraProperties)
siteConfig: union(siteconfig, commonSiteConfig)
httpsOnly: true
serverFarmId: server_farm_id
clientAffinityEnabled: true
}, extraProperties)
}

resource funcAuthSettings 'Microsoft.Web/sites/config@2021-03-01' = {
name: 'authsettingsV2'
properties: {
login:{
login: {
tokenStore: {
enabled: true
}
}
globalValidation: {
unauthenticatedClientAction: 'RedirectToLoginPage'
requireAuthentication: true
excludedPaths: [ '/api/config' ]
}
httpSettings: {
requireHttps: true
Expand Down
8 changes: 7 additions & 1 deletion src/deployment/config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{
"tenant_id": "72f988bf-86f1-41af-91ab-2d7cd011db47",
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
"tenant_domain": "azurewebsites.net",
"multi_tenant_domain": "",
"cli_client_id": "72f1562a-8c0c-41ea-beb9-fa2b71c80134",
"proxy_nsg_config": {
"allowed_ips": ["*"],
"allowed_ips": [
nharper285 marked this conversation as resolved.
Show resolved Hide resolved
"*"
],
"allowed_service_tags": []
}
}
Loading