1 /**
2 	Copyright: © 2013 rejectedsoftware e.K.
3 	License: Subject to the terms of the GNU GPLv3 license, as written in the included LICENSE.txt file.
4 	Authors: Sönke Ludwig
5 */
6 module app;
7 
8 import dubregistry.dbcontroller;
9 import dubregistry.mirror;
10 import dubregistry.repositories.bitbucket;
11 import dubregistry.repositories.github;
12 import dubregistry.repositories.gitlab;
13 import dubregistry.registry;
14 import dubregistry.web;
15 import dubregistry.api;
16 
17 import std.algorithm : sort;
18 import std.file;
19 import std.path;
20 import userman.web;
21 import vibe.d;
22 
23 
24 Task s_checkTask;
25 DubRegistry s_registry;
26 DubRegistryWebFrontend s_web;
27 string s_mirror;
28 
29 void startMonitoring()
30 {
31 	void monitorPackages()
32 	{
33 		sleep(1.seconds()); // give the cache a chance to warm up first
34 		while(true){
35 			if (s_mirror.length) s_registry.mirrorRegistry(s_mirror);
36 			else s_registry.updatePackages();
37 			sleep(30.minutes());
38 		}
39 	}
40 	s_checkTask = runTask(&monitorPackages);
41 }
42 
43 version (linux) private immutable string certPath;
44 
45 shared static this()
46 {
47 	bool noMonitoring;
48 	setLogFile("log.txt", LogLevel.diagnostic);
49 
50 	string hostname = "code.dlang.org";
51 
52 	readOption("mirror", &s_mirror, "URL of a package registry that this instance should mirror (WARNING: will overwrite local database!)");
53 	readOption("hostname", &hostname, "Domain name of this instance (default: code.dlang.org)");
54 	readOption("no-monitoring", &noMonitoring, "Don't periodically monitor for updates (for local development)");
55 
56 	// validate provided mirror URL
57 	if (s_mirror.length)
58 		validateMirrorURL(s_mirror);
59 
60 	version (linux) {
61 		logInfo("Enforcing certificate trust.");
62 		enum debianCA = "/etc/ssl/certs/ca-certificates.crt";
63 		enum redhatCA = "/etc/pki/tls/certs/ca-bundle.crt";
64 		certPath = redhatCA.exists ? redhatCA : debianCA;
65 
66 		HTTPClient.setTLSSetupCallback((ctx) {
67 			ctx.useTrustedCertificateFile(certPath);
68 			ctx.peerValidationMode = TLSPeerValidationMode.trustedCert;
69 		});
70 	}
71 
72 	import dub.internal.utils : jsonFromFile;
73 	auto regsettingsjson = jsonFromFile(NativePath("settings.json"), true);
74 	auto ghuser = regsettingsjson["github-user"].opt!string;
75 	auto ghpassword = regsettingsjson["github-password"].opt!string;
76 	auto glurl = regsettingsjson["gitlab-url"].opt!string;
77 	auto glauth = regsettingsjson["gitlab-auth"].opt!string;
78 
79 	GithubRepository.register(ghuser, ghpassword);
80 	BitbucketRepository.register();
81 	if (glurl.length) GitLabRepository.register(glauth, glurl);
82 
83 	auto router = new URLRouter;
84 	if (s_mirror.length) router.any("*", (req, res) { req.params["mirror"] = s_mirror; });
85 	if (!noMonitoring)
86 		router.get("*", (req, res) @trusted { if (!s_checkTask.running) startMonitoring(); });
87 
88 	// VPM registry
89 	auto regsettings = new DubRegistrySettings;
90 	s_registry = new DubRegistry(regsettings);
91 
92 	UserManController userdb;
93 
94 	if (!s_mirror.length) {
95 		// user management
96 		auto udbsettings = new UserManSettings;
97 		udbsettings.serviceName = "DUB - The D package registry";
98 		udbsettings.serviceURL = URL("http://code.dlang.org/");
99 		udbsettings.serviceEmail = "noreply@vibed.org";
100 		udbsettings.databaseURL = "mongodb://127.0.0.1:27017/vpmreg";
101 		udbsettings.requireActivation = false;
102 		userdb = createUserManController(udbsettings);
103 	}
104 
105 	// web front end
106 	s_web = router.registerDubRegistryWebFrontend(s_registry, userdb);
107 	router.registerDubRegistryAPI(s_registry);
108 
109 	// start the web server
110 	auto settings = new HTTPServerSettings;
111 	settings.hostName = hostname;
112 	settings.bindAddresses = ["127.0.0.1"];
113 	settings.port = 8005;
114 	settings.sessionStore = new MemorySessionStore;
115 	readOption("bind", &settings.bindAddresses[0], "Sets the address used for serving.");
116 	readOption("port|p", &settings.port, "Sets the port used for serving.");
117 
118 	listenHTTP(settings, router);
119 
120 	// poll github for new project versions
121 	if (!noMonitoring)
122 		startMonitoring();
123 }