diff --git a/bin/packages b/bin/packages new file mode 120000 index 00000000..a16c4050 --- /dev/null +++ b/bin/packages @@ -0,0 +1 @@ +../packages \ No newline at end of file diff --git a/bin/server.dart b/bin/server.dart index 3c391da9..c6ce22b6 100644 --- a/bin/server.dart +++ b/bin/server.dart @@ -4,17 +4,21 @@ import 'package:angel/angel.dart'; import 'package:angel_framework/angel_framework.dart'; main() async { - Angel app = await createServer(); + runZoned(startServer, onError: onError); +} - runZoned(() async { - await app.startServer( - new InternetAddress(app.properties['host']), app.properties['port']); - print("Angel server listening on ${app.httpServer.address.host}:${app - .httpServer.port}"); - }, onError: (error, [StackTrace stackTrace]) { - stderr.writeln("Unhandled error occurred: $error"); - if (stackTrace != null) { - stderr.writeln(stackTrace); - } - }); -} \ No newline at end of file +startServer() async { + Angel app = await createServer(); + InternetAddress host = new InternetAddress(app.properties['host']); + int port = app.properties['port']; + + await app.startServer(host, port); + print("Angel server listening on ${host.address}:${port}"); +} + +onError(error, [StackTrace stackTrace]) { + stderr.writeln("Unhandled error occurred: $error"); + if (stackTrace != null) { + stderr.writeln(stackTrace); + } +} diff --git a/config/default.yaml b/config/default.yaml index 0e200f66..592be3d7 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -1,2 +1,3 @@ # Default server configuration. -host: 127.0.0.1 \ No newline at end of file +host: 127.0.0.1 +mongo_db: mongodb://localhost:27017/angel \ No newline at end of file diff --git a/lib/angel.dart b/lib/angel.dart index 59f35b76..17bfe66a 100644 --- a/lib/angel.dart +++ b/lib/angel.dart @@ -3,13 +3,17 @@ library angel; import 'dart:async'; import 'package:angel_framework/angel_framework.dart'; -import 'src/config/config.dart' show configureServer; +import 'src/config/config.dart' as configuration; +import 'src/routes/routes.dart' as routes; +import 'src/services/services.dart' as services; /// Creates and configures the server instance. Future createServer() async { Angel app = new Angel(); - await app.configure(configureServer); + await app.configure(configuration.configureServer); + await app.configure(services.configureServer); + await app.configure(routes.configureServer); return app; } \ No newline at end of file diff --git a/lib/src/config/config.dart b/lib/src/config/config.dart index a8e52a39..70187e13 100644 --- a/lib/src/config/config.dart +++ b/lib/src/config/config.dart @@ -2,13 +2,31 @@ library angel.config; import 'dart:io'; +import 'package:angel_auth/angel_auth.dart'; import 'package:angel_configuration/angel_configuration.dart'; import 'package:angel_framework/angel_framework.dart'; import 'package:angel_mustache/angel_mustache.dart'; -import 'routes.dart'; +/// This is a perfect place to include configuration and load plug-ins. configureServer(Angel app) async { + AngelAuthOptions localOpts = new AngelAuthOptions( + failureRedirect: '/failure', successRedirect: '/success'); + Map sampleUser = {'hello': 'world'}; + + verifier(username, password) async { + if (username == 'username' && password == 'password') { + return sampleUser; + } else + return false; + } + + wireAuth(Angel app) async { + Auth.serializer = (user) async => 1337; + Auth.deserializer = (id) async => sampleUser; + + Auth.strategies.add(new LocalAuthStrategy(verifier)); + await app.configure(AngelAuth); + } await app.configure(loadConfigurationFile()); await app.configure(mustache(new Directory('views'))); - await app.configure(configureRoutes); -} \ No newline at end of file +} diff --git a/lib/src/config/routes.dart b/lib/src/routes/routes.dart similarity index 65% rename from lib/src/config/routes.dart rename to lib/src/routes/routes.dart index ef46ce30..2801c48a 100644 --- a/lib/src/config/routes.dart +++ b/lib/src/routes/routes.dart @@ -4,18 +4,28 @@ library angel.routes; import 'package:angel_framework/angel_framework.dart'; import 'package:angel_static/angel_static.dart'; +configureBefore(Angel app) async {} + /// Put your app routes here! configureRoutes(Angel app) async { app.get('/', (req, ResponseContext res) => res.render('hello')); app.all('*', serveStatic()); +} +configureAfter(Angel app) async { // 404 handler app.after.add((RequestContext req, ResponseContext res) async { res.willCloseItself = true; res.status(404); res.header('Content-Type', 'text/html'); - res.underlyingResponse.write( - await app.viewGenerator('404', {'path': req.path})); + res.underlyingResponse + .write(await app.viewGenerator('404', {'path': req.path})); await res.underlyingResponse.close(); }); -} \ No newline at end of file +} + +configureServer(Angel app) async { + await configureBefore(app); + await configureRoutes(app); + await configureAfter(app); +} diff --git a/lib/src/services/services.dart b/lib/src/services/services.dart new file mode 100644 index 00000000..7e107dd4 --- /dev/null +++ b/lib/src/services/services.dart @@ -0,0 +1,14 @@ +/// Declare services here! +library angel.services; + +import 'package:angel_framework/angel_framework.dart'; +import 'package:mongo_dart/mongo_dart.dart'; + +import 'users/users.dart' as Users; + +configureServer(Angel app) async { + Db db = new Db(app.properties["mongo_db"]); + await db.open(); + + await app.configure(Users.configureServer(db)); +} diff --git a/lib/src/services/users/schema.dart b/lib/src/services/users/schema.dart new file mode 100644 index 00000000..075296e8 --- /dev/null +++ b/lib/src/services/users/schema.dart @@ -0,0 +1 @@ +const Map UserSchema = const {}; \ No newline at end of file diff --git a/lib/src/services/users/users.dart b/lib/src/services/users/users.dart new file mode 100644 index 00000000..f95c0e0c --- /dev/null +++ b/lib/src/services/users/users.dart @@ -0,0 +1,40 @@ +import 'package:angel_framework/angel_framework.dart'; +import 'package:angel_mongo/angel_mongo.dart'; +import 'package:crypto/crypto.dart' show sha256; +import 'package:json_god/json_god.dart' as god; +import 'package:mongo_dart/mongo_dart.dart'; +import 'schema.dart'; + +@god.WithSchema(UserSchema) +class User extends Model { + String email; + String username; + String password; + List roles; + + User( + {String this.email, + String this.username, + String this.password, + List roles}) { + this.roles = roles ?? []; + } +} + +hashPassword(HookedServiceEvent event) { + if (event.data.password != null) { + event.data.password = + sha256.convert(event.data.password.codeUnits).toString(); + } +} + +configureServer(Db db) { + return (Angel app) async { + app.use("/api/users", new MongoTypedService(db.collection("users"))); + + HookedService service = app.service("api/users"); + + // Place your hooks here! + service.beforeCreated.listen(hashPassword); + }; +} diff --git a/pubspec.yaml b/pubspec.yaml index 7d440edf..07fce40e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,8 +4,10 @@ version: 0.0.0-dev.0 author: thosakwe homepage: https://github.com/angel-dart/angel dependencies: + angel_auth: ">=1.0.0-dev <2.0.0" angel_configuration: ">=1.0.0-dev <2.0.0" angel_framework: ">=1.0.0-dev <2.0.0" + angel_mongo: ">=1.0.0-dev <2.0.0" angel_mustache: ">=1.0.0-dev <2.0.0" angel_static: ">=1.0.0 <1.1.0" json_god: ">=2.0.0-beta <3.0.0" diff --git a/test/services/users.dart b/test/services/users.dart new file mode 100644 index 00000000..9519d5df --- /dev/null +++ b/test/services/users.dart @@ -0,0 +1,35 @@ +import 'dart:io'; +import 'package:angel/angel.dart'; +import 'package:angel_framework/angel_framework.dart'; +import 'package:http/http.dart'; +import 'package:json_god/json_god.dart' as god; +import 'package:test/test.dart'; + +main() async { + group('services.users', () { + Angel app; + Client client = new Client(); + Map headers = { + HttpHeaders.ACCEPT: ContentType.JSON.mimeType, + HttpHeaders.CONTENT_TYPE: ContentType.JSON.mimeType + }; + HttpServer server; + String url; + + setUp(() async { + Angel app = await createServer(); + server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 3000); + url = "http://localhost:3000"; + }); + + tearDown(() async { + await server.close(force: true); + client.close(); + }); + + test('index users', () async { + Response response = await client.get("$url/api/users"); + expect(response.statusCode, equals(HttpStatus.OK)); + }); + }); +} diff --git a/web/packages b/web/packages new file mode 120000 index 00000000..a16c4050 --- /dev/null +++ b/web/packages @@ -0,0 +1 @@ +../packages \ No newline at end of file