conduit 5.1.1 conduit: ^5.1.1 copied to clipboard
A modern HTTP server application framework, ORM and OAuth2 provider with OpenAPI 3.0 integration. Foundation for REST, RPC or GraphQL services.
/*
This example demonstrates an HTTP application that uses the ORM and ORM-backed OAuth2 provider.
For building and running non-example applications, install 'conduit' command-line tool.
pub global activate conduit
conduit create my_app
More examples available: https://github.com/conduit.dart/conduit_examples
*/
import 'dart:async';
import 'dart:io';
import 'package:conduit_core/conduit_core.dart';
import 'package:conduit_core/managed_auth.dart';
import 'package:conduit_postgresql/conduit_postgresql.dart';
Future main() async {
final app = Application<App>()
..options.configurationFilePath = 'config.yaml'
..options.port = 8888;
await app.start(numberOfInstances: 3);
}
class App extends ApplicationChannel {
late ManagedContext context;
late final AuthServer authServer;
@override
Future prepare() async {
final config =
AppConfiguration.fromFile(File(options!.configurationFilePath!));
final db = config.database;
final persistentStore = PostgreSQLPersistentStore.fromConnectionInfo(
db.username,
db.password,
db.host,
db.port,
db.databaseName,
);
context = ManagedContext(
ManagedDataModel.fromCurrentMirrorSystem(),
persistentStore,
);
authServer = AuthServer(ManagedAuthDelegate(context));
}
@override
Controller get entryPoint {
return Router()
..route('/auth/token').link(() => AuthController(authServer))
..route('/users/[:id]')
.link(() => Authorizer(authServer))!
.link(() => UserController(context, authServer));
}
}
class UserController extends ResourceController {
UserController(this.context, this.authServer);
final ManagedContext? context;
final AuthServer authServer;
@Operation.get()
Future<Response> getUsers() async {
final query = Query<User>(context!);
return Response.ok(await query.fetch());
}
@Operation.get('id')
Future<Response> getUserById(@Bind.path('id') int id) async {
final q = Query<User>(context!)..where((o) => o.id).equalTo(id);
final user = await q.fetchOne();
if (user == null) {
return Response.notFound();
}
return Response.ok(user);
}
@Operation.post()
Future<Response> createUser(@Bind.body() User user) async {
if (user.username == null || user.password == null) {
return Response.badRequest(
body: {"error": "username and password required."},
);
}
final salt = generateRandomSalt();
final hashedPassword = authServer.hashPassword(user.password!, salt);
final query = Query<User>(context!)
..values = user
..values.hashedPassword = hashedPassword
..values.salt = salt
..values.email = user.username;
final u = await query.insert();
final token = await authServer.authenticate(
u.username,
query.values.password,
request!.authorization!.credentials!.username,
request!.authorization!.credentials!.password,
);
return AuthController.tokenResponse(token);
}
}
class AppConfiguration extends Configuration {
AppConfiguration.fromFile(super.file) : super.fromFile();
late DatabaseConfiguration database;
}
class User extends ManagedObject<_User>
implements _User, ManagedAuthResourceOwner<_User> {
@Serialize(input: true, output: false)
String? password;
}
class _User extends ResourceOwnerTableDefinition {
@Column(unique: true)
String? email;
}