Skip to content

Commit 0ba4d66

Browse files
authored
DRV-378: Support for 3rd party auth APIv4 (#134)
1 parent 195697f commit 0ba4d66

File tree

6 files changed

+311
-12
lines changed

6 files changed

+311
-12
lines changed

.circleci/config.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ executors:
1111
docker:
1212
- image: mcr.microsoft.com/dotnet/core/sdk:3.1
1313

14-
- image: fauna/faunadb
14+
- image: gcr.io/faunadb-cloud/faunadb/enterprise/<<parameters.version>>:latest
1515
name: core
16+
auth:
17+
username: _json_key
18+
password: $GCR_KEY
1619

1720
environment:
1821
FAUNA_ROOT_KEY: secret

FaunaDB.Client.Test/ClientTest.cs

Lines changed: 192 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ namespace Test
1919
public class ClientTest : TestCase
2020
{
2121
private static Field<Value> DATA = Field.At("data");
22+
private static Field<Value> ROLES = Field.At("roles");
2223
private static Field<long> TS_FIELD = Field.At("ts").To<long>();
2324
private static Field<RefV> DOCUMENT_FIELD = Field.At("document").To<RefV>();
25+
private static Field<string> AUTH_NAME_FIELD = Field.At("name").To<string>();
26+
private static Field<string> ISSUER_FIELD = Field.At("issuer").To<string>();
27+
private static Field<string> JWKS_URI_FIELD = Field.At("jwks_uri").To<string>();
28+
private static Field<string> AUDIENCE_FIELD = Field.At("audience").To<string>();
2429
private static Field<IReadOnlyList<RefV>> REF_LIST = DATA.Collect(Field.To<RefV>());
30+
private static Field<IReadOnlyList<RefV>> ROLES_LIST = ROLES.Collect(Field.To<RefV>());
2531

2632
private static Field<string> NAME_FIELD = DATA.At(Field.At("name")).To<string>();
2733
private static Field<string> ELEMENT_FIELD = DATA.At(Field.At("element")).To<string>();
@@ -1533,7 +1539,7 @@ public async Task TestVersionedQuery()
15331539
{
15341540
{"lambda", Arr("x", "y")},
15351541
{"expr", Concat(Arr(Var("x"), "/", Var("y")))},
1536-
{ "api_version", "3" }
1542+
{ "api_version", "4" }
15371543
}));
15381544
}
15391545

@@ -2096,7 +2102,7 @@ public async Task TestRequestMessageHeaders()
20962102

20972103
var headers = customHttp.LastMessage.Headers;
20982104
Assert.AreEqual("csharp", headers.GetValues("X-Fauna-Driver").First());
2099-
Assert.AreEqual("3", headers.GetValues("X-FaunaDB-API-Version").First());
2105+
Assert.AreEqual("4", headers.GetValues("X-FaunaDB-API-Version").First());
21002106
Assert.IsFalse(headers.Contains("X-Last-Seen-Txn"));
21012107

21022108
// the default HttpClient.Timeout is 100 seconds
@@ -2114,7 +2120,7 @@ public async Task TestRequestMessageHeaders()
21142120

21152121
headers = customHttp.LastMessage.Headers;
21162122

2117-
Assert.AreEqual("3", headers.GetValues("X-FaunaDB-API-Version").First());
2123+
Assert.AreEqual("4", headers.GetValues("X-FaunaDB-API-Version").First());
21182124
Assert.AreEqual("42000", headers.GetValues("X-Query-Timeout").First());
21192125
Assert.IsTrue(long.Parse(headers.GetValues("X-Last-Seen-Txn").First()) > 0);
21202126

@@ -2166,6 +2172,189 @@ public async Task TestCustomHttp()
21662172
Assert.AreEqual(faunaEndpoint, myHttpClient.LastMessage.RequestUri.ToString());
21672173
}
21682174

2175+
[Test]
2176+
public async Task TestAuthProviders()
2177+
{
2178+
string roleName = RandomStartingWith("role_");
2179+
string accessProviderName = RandomStartingWith("access_prov_");
2180+
string issuerName = RandomStartingWith("issuer_");
2181+
string jwksUri = "https://xxxx.auth0.com/";
2182+
2183+
RefV collection = await RandomCollection();
2184+
2185+
RefV role = GetRef(await adminClient.Query(CreateRole(Obj(
2186+
"name", roleName,
2187+
"privileges", Arr(Obj(
2188+
"resource", collection,
2189+
"actions", Obj("read", true)
2190+
))
2191+
))));
2192+
2193+
Value accessProvider = await adminClient.Query(CreateAccessProvider(
2194+
Obj(
2195+
"name", accessProviderName,
2196+
"issuer", issuerName,
2197+
"jwks_uri", jwksUri,
2198+
"roles", Arr(role)
2199+
)));
2200+
2201+
var roles = accessProvider.Get(ROLES_LIST);
2202+
Assert.AreEqual(1, roles.Count);
2203+
2204+
Assert.AreEqual(
2205+
accessProviderName,
2206+
accessProvider.Get(AUTH_NAME_FIELD));
2207+
2208+
Assert.AreEqual(
2209+
issuerName,
2210+
accessProvider.Get(ISSUER_FIELD));
2211+
2212+
Assert.AreEqual(
2213+
"https://xxxx.auth0.com/",
2214+
accessProvider.Get(JWKS_URI_FIELD));
2215+
2216+
Assert.IsNotEmpty(accessProvider.Get(AUDIENCE_FIELD));
2217+
2218+
// Retrieving
2219+
2220+
var accessProviderFromDb =
2221+
await adminClient.Query(Get(AccessProvider(accessProviderName)));
2222+
2223+
Assert.AreEqual(accessProvider, accessProviderFromDb);
2224+
Assert.AreEqual(
2225+
jwksUri,
2226+
accessProviderFromDb.Get(JWKS_URI_FIELD));
2227+
2228+
// Retrieving: Denied
2229+
2230+
var ex = Assert.ThrowsAsync<PermissionDenied>(
2231+
async () => await client.Query(Get(AccessProvider(accessProviderName)))
2232+
);
2233+
2234+
AssertErrors(ex, code: "permission denied", description: "Insufficient privileges to perform the action.");
2235+
AssertEmptyFailures(ex);
2236+
AssertPosition(ex, positions: Is.EquivalentTo(new List<string> { }));
2237+
2238+
// Paginating
2239+
2240+
var otherName = RandomStartingWith("ap_");
2241+
2242+
await adminClient.Query(CreateAccessProvider(
2243+
Obj(
2244+
"name", otherName,
2245+
"issuer", RandomStartingWith("ap_"),
2246+
"jwks_uri", jwksUri
2247+
)));
2248+
2249+
Value page = await adminClient.Query(Paginate(AccessProviders()));
2250+
var pageData = page.Get(REF_LIST);
2251+
2252+
Assert.AreEqual(2, pageData.Count);
2253+
Assert.AreEqual(accessProviderName, pageData.First().Id);
2254+
Assert.AreEqual(otherName, pageData.Last().Id);
2255+
}
2256+
2257+
[Test]
2258+
public async Task TestCurrentIdentity()
2259+
{
2260+
Value createdInstance = await adminClient.Query(
2261+
Create(await RandomCollection(),
2262+
Obj("credentials",
2263+
Obj("password", "sekret"))));
2264+
2265+
Value auth = await adminClient.Query(
2266+
Login(createdInstance.At("ref"),
2267+
Obj("password", "sekret")
2268+
)
2269+
);
2270+
2271+
string secret = auth.Get(SECRET_FIELD);
2272+
2273+
FaunaClient sessionClient = adminClient.NewSessionClient(secret);
2274+
Assert.AreEqual(createdInstance.Get(REF_FIELD), await sessionClient.Query(CurrentIdentity()));
2275+
}
2276+
2277+
[Test]
2278+
public async Task TestHasCurrentIdentity()
2279+
{
2280+
Value createdInstance = await adminClient.Query(
2281+
Create(await RandomCollection(),
2282+
Obj("credentials",
2283+
Obj("password", "sekret"))));
2284+
2285+
Value auth = await adminClient.Query(
2286+
Login(createdInstance.Get(REF_FIELD),
2287+
Obj("password", "sekret")
2288+
)
2289+
);
2290+
2291+
string secret = auth.Get(SECRET_FIELD);
2292+
2293+
FaunaClient sessionClient = adminClient.NewSessionClient(secret);
2294+
Assert.IsTrue((await sessionClient.Query(HasCurrentIdentity())).To<bool>().Value);
2295+
}
2296+
2297+
[Test]
2298+
public async Task TestCurrentTokenWithInternalToken()
2299+
{
2300+
Value createdInstance = await adminClient.Query(
2301+
Create(await RandomCollection(),
2302+
Obj("credentials",
2303+
Obj("password", "sekret"))));
2304+
2305+
Value auth = await adminClient.Query(
2306+
Login(createdInstance.At("ref"),
2307+
Obj("password", "sekret")
2308+
)
2309+
);
2310+
2311+
string secret = auth.Get(SECRET_FIELD);
2312+
Value tokenRef = auth.Get(REF_FIELD);
2313+
2314+
FaunaClient sessionClient = adminClient.NewSessionClient(secret);
2315+
Assert.AreEqual(tokenRef, await sessionClient.Query(CurrentToken()));
2316+
}
2317+
2318+
[Test]
2319+
public async Task TestCurrentTokenWithInternalKey()
2320+
{
2321+
Value clientKey = await adminClient.Query(
2322+
CreateKey(Obj("role", "client"))
2323+
);
2324+
2325+
string secret = clientKey.Get(SECRET_FIELD);
2326+
Value keyRef = clientKey.Get(REF_FIELD);
2327+
2328+
FaunaClient sessionClient = adminClient.NewSessionClient(secret);
2329+
Assert.AreEqual(keyRef, await sessionClient.Query(CurrentToken()));
2330+
}
2331+
2332+
[Test]
2333+
public async Task TestHasCurrentTokenWithInternalToken()
2334+
{
2335+
Value createdInstance = await adminClient.Query(
2336+
Create(await RandomCollection(),
2337+
Obj("credentials",
2338+
Obj("password", "sekret"))));
2339+
2340+
Value auth = await adminClient.Query(
2341+
Login(createdInstance.At("ref"),
2342+
Obj("password", "sekret")
2343+
)
2344+
);
2345+
2346+
string secret = auth.Get(SECRET_FIELD);
2347+
2348+
FaunaClient sessionClient = adminClient.NewSessionClient(secret);
2349+
Assert.IsTrue((await sessionClient.Query(HasCurrentToken())).To<bool>().Value);
2350+
}
2351+
2352+
[Test]
2353+
public async Task TestHasCurrentTokenWithInternalKey()
2354+
{
2355+
Assert.IsFalse((await adminClient.Query(HasCurrentToken())).To<bool>().Value);
2356+
}
2357+
21692358
private async Task<Value> NewCollectionWithValues(string colName, string indexName, int size = 10, bool indexWithAllValues = false)
21702359
{
21712360
RefV aCollection = (await client.Query(CreateCollection(Obj("name", colName))))

FaunaDB.Client.Test/SerializationTest.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,12 +556,55 @@ [Test] public void TestIdentity()
556556
AssertJsonEqual(Identity(),
557557
"{\"identity\":null}");
558558
}
559+
560+
[Test] public void TestCurrentIdentity()
561+
{
562+
AssertJsonEqual(CurrentIdentity(),
563+
"{\"current_identity\":null}");
564+
}
559565

560566
[Test] public void TestHasIdentity()
561567
{
562568
AssertJsonEqual(HasIdentity(),
563569
"{\"has_identity\":null}");
564570
}
571+
572+
[Test] public void TestHasCurrentIdentity()
573+
{
574+
AssertJsonEqual(HasCurrentIdentity(),
575+
"{\"has_current_identity\":null}");
576+
}
577+
578+
[Test] public void TestCurrentToken()
579+
{
580+
AssertJsonEqual(CurrentToken(),
581+
"{\"current_token\":null}");
582+
}
583+
584+
[Test] public void TestHasCurrentToken()
585+
{
586+
AssertJsonEqual(HasCurrentToken(),
587+
"{\"has_current_token\":null}");
588+
}
589+
590+
[Test] public void TestCreateAccessProvider()
591+
{
592+
AssertJsonEqual(CreateAccessProvider(
593+
Obj(
594+
"name", "role_name",
595+
"issuer", "issuer_name",
596+
"jwks_uri", "https://auth0.com",
597+
"membership", Arr()
598+
)),
599+
"{\"create_access_provider\":{\"object\":{\"name\":\"role_name\",\"issuer\":\"issuer_name\",\"jwks_uri\":\"https://auth0.com\",\"membership\":[]}}}");
600+
}
601+
602+
[Test]
603+
public void TestAccessProvider()
604+
{
605+
AssertJsonEqual(AccessProvider("access-provider"),
606+
"{\"access_provider\":\"access-provider\"}");
607+
}
565608

566609
[Test] public void TestConcat()
567610
{

FaunaDB.Client/Client/DefaultClientIO.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ async Task<RequestResult> DoRequestAsync(HttpMethodKind method, string path, str
6565
message.Headers.Authorization = authHeader;
6666
message.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
6767
message.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
68-
message.Headers.Add("X-FaunaDB-API-Version", "3");
68+
message.Headers.Add("X-FaunaDB-API-Version", "4");
6969
message.Headers.Add("X-Fauna-Driver", "csharp");
7070

7171
var last = lastSeen.Txn;
@@ -163,12 +163,11 @@ static IReadOnlyDictionary<string, IEnumerable<string>> ToDictionary(HttpRespons
163163
headers.ToDictionary(k => k.Key, v => v.Value);
164164

165165
/// <summary>
166-
/// Encodes secret string using base64.
166+
/// Adds a header with Bearer Auth Token.
167167
/// </summary>
168-
static AuthenticationHeaderValue AuthHeader(string secret)
168+
static AuthenticationHeaderValue AuthHeader(string authToken)
169169
{
170-
var bytes = Encoding.ASCII.GetBytes(secret);
171-
return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(bytes));
170+
return new AuthenticationHeaderValue("Bearer", authToken);
172171
}
173172

174173
/// <summary>

0 commit comments

Comments
 (0)