Skip to content

Commit

Permalink
Test Custom JWT Authentication to Credentials (#715)
Browse files Browse the repository at this point in the history
* Add Custom JWT Authentication to Credentials
* Test Custom JWT Authentication with custom token
  • Loading branch information
desistefanova authored Aug 12, 2022
1 parent 82db10e commit 0c99911
Show file tree
Hide file tree
Showing 13 changed files with 371 additions and 76 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,8 @@ jobs:

# This will be a no-op under normal circumstances since the cluster would have been deployed
# in deploy-cluster. It is needed in case we want to re-run the job after the cluster has been reaped.
- uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
- name: Create cluster
uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
with:
realmUrl: ${{ env.BAAS_URL }}
atlasUrl: ${{ secrets.ATLAS_QA_URL }}
Expand Down Expand Up @@ -376,7 +377,8 @@ jobs:

# This will be a no-op under normal circumstances since the cluster would have been deployed
# in deploy-cluster. It is needed in case we want to re-run the job after the cluster has been reaped.
- uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
- name: Create cluster
uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
with:
realmUrl: ${{ env.BAAS_URL }}
atlasUrl: ${{ secrets.ATLAS_QA_URL }}
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/dart-desktop-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ jobs:

# This will be a no-op under normal circumstances since the cluster would have been deployed
# in deploy-cluster. It is needed in case we want to re-run the job after the cluster has been reaped.
- uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
- name: Create cluster
uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
with:
realmUrl: ${{ env.BAAS_URL }}
atlasUrl: ${{ secrets.ATLAS_QA_URL }}
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/flutter-desktop-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ jobs:

# This will be a no-op under normal circumstances since the cluster would have been deployed
# in deploy-cluster. It is needed in case we want to re-run the job after the cluster has been reaped.
- uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
- name: Create cluster
uses: realm/ci-actions/mdb-realm/deployApps@3f810b2d04e9dada2bde0b33ec90102e52a0b30a
with:
realmUrl: ${{ env.BAAS_URL }}
atlasUrl: ${{ secrets.ATLAS_QA_URL }}
Expand Down
3 changes: 3 additions & 0 deletions .pubignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ src/realm-core/**/*.pem
# Ignore realm-core doc
src/realm-core/doc

# Ignore test resources
test/data

1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Support `App.deleteUser ` for deleting user accounts. ([#679](https://github.com/realm/realm-dart/pull/679))
* Support Apple, Facebook and Google authentication. ([#740](https://github.com/realm/realm-dart/pull/740))
* Allow multiple anonymous sessions. When using anonymous authentication you can now easily log in with a different anonymous user than last time. ([#750](https://github.com/realm/realm-dart/pull/750)).
* Support `Credentials.jwt` for login user with JWT issued by custom provider . ([#715](https://github.com/realm/realm-dart/pull/715))

### Internal
* Added a command to `realm_dart` for deleting Atlas App Services applications. Usage: `dart run realm_dart delete-apps`. By default it will delete apps from `http://localhost:9090` which is the endpoint of the local docker image. If `--atlas-cluster` is provided, it will authenticate, delete the application from the provided cluster. (PR [#663](https://github.com/realm/realm-dart/pull/663))
Expand Down
71 changes: 71 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,74 @@ We love contributions to Realm! If you'd like to contribute code, documentation,
Realm welcomes all contributions! The only requirement we have is that, like many other projects, we need to have a [Contributor License Agreement](https://en.wikipedia.org/wiki/Contributor_License_Agreement) (CLA) in place before we can accept any external code. Our own CLA is a modified version of the Apache Software Foundation’s CLA.

[Please submit your CLA electronically using our Google form](https://docs.google.com/forms/d/1ga5zIS9qnwwFPmbq-orSPsiBIXQjltKg7ytHd2NmDYo/viewform) so we can accept your submissions. The GitHub username you file there will need to match that of your Pull Requests. If you have any questions or cannot file the CLA electronically, you can email <[email protected]>.

## Building the source

### Building Realm Flutter

* Clone the repo
```
git clone https://github.com/realm/realm-dart
git submodule update --init --recursive
```

#### Build Realm Flutter native binaries

* Android
```bash
./scripts/build-android.sh all
scripts\build-android.bat all
# Or for Android Emulator only
./scripts/build-android.sh x86
scripts\build-android.bat x86
```

* iOS
```bash
./scripts/build-ios.sh
# Or for iOS Simulator only
./scripts/build-ios.sh simulator
```

* Windows
```
scripts\build.bat
```
* MacOS
```
./scripts/build-macos.sh
```

* Linux
```
./scripts/build-linux.sh
```

### Building Realm Dart

* Windows
```
scripts\build.bat
```
* MacOS
```
./scripts/build-macos.sh
```
* Linux
```
./scripts/build-linux.sh
```

## Running tests

See [test/README.md](https://github.com/realm/realm-dart/blob/master/test/README.md) for instructions on running tests.

## Versioning

Realm Flutter and Dart SDK packages follow [Semantic Versioning](https://semver.org/).
During the initial development the packages will be versioned according the scheme `0.major.minor+release stage` until the first stable version is reached then packages will be versioned with `major.minor.patch` scheme.

The first versions will follow `0.1.0+preview`, `0.1.1+preview` etc.
Then next release stages will pick up the next minor version `0.1.2+beta`, `0.1.3+beta`. This will ensure dependencies are updated on `dart pub get` with the new `alpha`, `beta` versions.
If an `alpha` version is released before `beta` and it needs to not be considered for `pub get` then it should be marked as `prerelease` with `-alpha` so `0.1.2-alpha` etc.
Updating the major version with every release stage is also possible - `0.2.0+alpha`, `0.3.0+beta`, `0.3.1+beta`.
68 changes: 2 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,76 +310,12 @@ The Realm Dart package is `realm_dart`

# Building the source

## Building Realm Flutter
See [CONTRIBUTING.md](https://github.com/realm/realm-dart/blob/master/CONTRIBUTING.md#building-the-source) for instructions about building the source.

* Clone the repo
```
git clone https://github.com/realm/realm-dart
git submodule update --init --recursive
```

### Build Realm Flutter native binaries

* Android
```bash
./scripts/build-android.sh all
scripts\build-android.bat all
# Or for Android Emulator only
./scripts/build-android.sh x86
scripts\build-android.bat x86
```

* iOS
```bash
./scripts/build-ios.sh
# Or for iOS Simulator only
./scripts/build-ios.sh simulator
```

* Windows
```
scripts\build.bat
```
* MacOS
```
./scripts/build-macos.sh
```

* Linux
```
./scripts/build-linux.sh
```

## Building Realm Dart

* Windows
```
scripts\build.bat
```
* MacOS
```
./scripts/build-macos.sh
```
* Linux
```
./scripts/build-linux.sh
```

## Running tests
# Running tests

See [test/README.md](https://github.com/realm/realm-dart/blob/master/test/README.md) for instructions on running tests.

## Versioning

Realm Flutter and Dart SDK packages follow [Semantic Versioning](https://semver.org/).
During the initial development the packages will be versioned according the scheme `0.major.minor+release stage` until the first stable version is reached then packages will be versioned with `major.minor.patch` scheme.

The first versions will follow `0.1.0+preview`, `0.1.1+preview` etc.
Then next release stages will pick up the next minor version `0.1.2+beta`, `0.1.3+beta`. This will ensure dependencies are updated on `dart pub get` with the new `alpha`, `beta` versions.
If an `alpha` version is released before `beta` and it needs to not be considered for `pub get` then it should be marked as `prerelease` with `-alpha` so `0.1.2-alpha` etc.
Updating the major version with every release stage is also possible - `0.2.0+alpha`, `0.3.0+beta`, `0.3.1+beta`.


# Code of Conduct

This project adheres to the [MongoDB Code of Conduct](https://www.mongodb.com/community-code-of-conduct).
Expand Down
66 changes: 63 additions & 3 deletions lib/src/cli/atlas_apps/baas_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class BaasClient {
late final String _appSuffix = '-${shortenDifferentiator(_differentiator)}-$_clusterName';

late String _groupId;
late String publicRSAKey = '';

BaasClient._(String baseUrl, String? differentiator, [this._clusterName])
: _baseUrl = '$baseUrl/api/admin/v3.0',
Expand Down Expand Up @@ -166,7 +167,7 @@ class BaasClient {
final resetFuncId = await _createFunction(app, 'resetFunc', _resetFuncSource);

await enableProvider(app, 'anon-user');
await enableProvider(app, 'local-userpass', '''{
await enableProvider(app, 'local-userpass', config: '''{
"autoConfirm": ${(confirmationType == "auto").toString()},
"confirmEmailSubject": "Confirmation required",
"confirmationFunctionName": "confirmFunc",
Expand All @@ -180,6 +181,63 @@ class BaasClient {
"runResetFunction": true
}''');

if (publicRSAKey.isNotEmpty) {
String publicRSAKeyEncoded = jsonEncode(publicRSAKey);
final dynamic createSecretResult = await _post('groups/$_groupId/apps/$appId/secrets', '{"name":"rsPublicKey","value":$publicRSAKeyEncoded}');
String keyName = createSecretResult['name'] as String;

await enableProvider(app, 'custom-token', config: '''{
"audience": "mongodb.com",
"signingAlgorithm": "RS256",
"useJWKURI": false
}''', secretConfig: '''{
"signingKeys": ["$keyName"]
}''', metadataFelds: '''{
"required": false,
"name": "name.firstName",
"field_name": "firstName"
},
{
"required": false,
"name": "name.lastName",
"field_name": "lastName"
},
{
"required": true,
"name": "email",
"field_name": "name"
},
{
"required": true,
"name": "email",
"field_name": "email"
},
{
"required": false,
"name": "gender",
"field_name": "gender"
},
{
"required": false,
"name": "birthDay",
"field_name": "birthDay"
},
{
"required": false,
"name": "minAge",
"field_name": "minAge"
},
{
"required": false,
"name": "maxAge",
"field_name": "maxAge"
},
{
"required": false,
"name": "company",
"field_name": "company"
}''');
}
print('Creating database db_$name$_appSuffix');

await _createMongoDBService(app, '''{
Expand Down Expand Up @@ -209,7 +267,7 @@ class BaasClient {
return app;
}

Future<void> enableProvider(BaasApp app, String type, [String config = '{}']) async {
Future<void> enableProvider(BaasApp app, String type, {String config = '{}', String secretConfig = '{}', String metadataFelds = '{}'}) async {
print('Enabling provider $type for ${app.clientAppId}');

final url = 'groups/$_groupId/apps/$app/auth_providers';
Expand All @@ -223,7 +281,9 @@ class BaasClient {
"name": "$type",
"type": "$type",
"disabled": false,
"config": $config
"config": $config,
"secret_config": $secretConfig,
"metadata_fields": [$metadataFelds]
}''');
}
}
Expand Down
9 changes: 8 additions & 1 deletion lib/src/credentials.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ enum AuthProviderType {
/// Authenticate with Google account
google,

_custom,
/// For authenticating with JSON web token.
jwt,

/// For authenticating with an email and a password.
emailPassword,
Expand Down Expand Up @@ -76,6 +77,12 @@ class Credentials {
: _handle = realmCore.createAppCredentialsEmailPassword(email, password),
provider = AuthProviderType.emailPassword;

/// Returns a [Credentials] object that can be used to authenticate a user with a custom JWT.
/// [Custom-JWT Authentication Docs](https://docs.mongodb.com/realm/authentication/custom-jwt)
Credentials.jwt(String token)
: _handle = realmCore.createAppCredentialsJwt(token),
provider = AuthProviderType.jwt;

/// Returns a [Credentials] object that can be used to authenticate a user with a Facebook account.
Credentials.facebook(String accessToken)
: _handle = realmCore.createAppCredentialsFacebook(accessToken),
Expand Down
7 changes: 7 additions & 0 deletions lib/src/native/realm_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -931,6 +931,13 @@ class _RealmCore {
});
}

RealmAppCredentialsHandle createAppCredentialsJwt(String token) {
return using((arena) {
final tokenPtr = token.toCharPtr(arena);
return RealmAppCredentialsHandle._(_realmLib.realm_app_credentials_new_jwt(tokenPtr));
});
}

RealmAppCredentialsHandle createAppCredentialsApple(String idToken) {
return using((arena) {
final idTokenPtr = idToken.toCharPtr(arena);
Expand Down
Loading

0 comments on commit 0c99911

Please sign in to comment.