Exemple #1
0
        public Yield Invoke(Plug plug, string verb, XUri uri, DreamMessage request, Result<DreamMessage> response)
        {
            // NOTE (steveb): we convert 'xri://@name/path?params' into 'http://xri.net/@name/path?params'

            // prepend segments with authority
            List<string> segments = new List<string>();
            segments.Add(uri.Authority);
            if(uri.Segments != null) {
                segments.AddRange(uri.Segments);
            }

            // build new plug
            List<PlugHandler> preHandlers = (plug.PreHandlers != null) ? new List<PlugHandler>(plug.PreHandlers) : null;
            List<PlugHandler> postHandlers = (plug.PostHandlers != null) ? new List<PlugHandler>(plug.PostHandlers) : null;
            Plug xri = new Plug(new XUri("http", null, null, "xri.net", 80, segments.ToArray(), uri.TrailingSlash, uri.Params, uri.Fragment), plug.Timeout, request.Headers, preHandlers, postHandlers, plug.Credentials, plug.CookieJar, plug.MaxAutoRedirects);

            // add 'Accept' header for 'application/xrds+xml' mime-type
            if((xri.Headers == null) || (xri.Headers.Accept == null)) {
                xri = xri.WithHeader(DreamHeaders.ACCEPT, MimeType.RenderAcceptHeader(MimeType.XRDS));
            }

            // BUGBUGBUG (steveb): this will probably fail in some cases since we may exit this coroutine before the call has completed!

            xri.InvokeEx(verb, request, response);
            yield break;
        }
Exemple #2
0
 private IEnumerator<IYield> AuthenticateImportUser(Plug api, string wikiId, string apikey, Result<Plug> result) {
     XDoc settings = null;
     yield return api.At("site", "settings").With("apikey", apikey).GetAsync().Set(x => settings = x.ToDocument());
     var username = settings["packageupdater/username"].AsText ?? settings["security/admin-user-for-impersonation"].AsText;
     string authToken = null;
     if(string.IsNullOrEmpty(username)) {
         _log.DebugFormat("[{0}] no user in 'packageupdater/username' config key, trying 'admin'", wikiId);
         username = "******";
         yield return Coroutine.Invoke(Authenticate, api, username, apikey, new Result<string>()).Set(x => authToken = x);
         if(string.IsNullOrEmpty(authToken)) {
             _log.DebugFormat("[{0}] 'admin' didn't authenticate, trying 'sysop'", wikiId);
             username = "******";
         }
     }
     if(string.IsNullOrEmpty(authToken)) {
         _log.DebugFormat("[{0}] authenticating as '{1}'", wikiId, username);
         yield return Coroutine.Invoke(Authenticate, api, username, apikey, new Result<string>()).Set(x => authToken = x);
     }
     if(string.IsNullOrEmpty(authToken)) {
         throw new UnauthorizedAccessException(string.Format("Unable to authenticate as '{0}'", username));
     }
     result.Return(api.WithHeader(DekiWikiService.AUTHTOKEN_HEADERNAME, authToken));
 }
Exemple #3
0
        private Yield SubscribeIndexer(Plug pubsubPlug, Result result) {
            _log.DebugFormat("subscribing indexer to pubsub {0}", pubsubPlug.Uri.ToString());
            var subscriptionSet = new XDoc("subscription-set")
                 .Elem("uri.owner", Self.Uri)
                 .Start("subscription")
                     .Add(DreamCookie.NewSetCookie("service-key", InternalAccessKey, Self.Uri).AsSetCookieDocument)
                     .Elem("channel", "event://*/deki/pages/noop")
                     .Elem("channel", "event://*/deki/pages/create")
                     .Elem("channel", "event://*/deki/pages/move")
                     .Elem("channel", "event://*/deki/pages/update")
                     .Elem("channel", "event://*/deki/pages/delete")
                     .Elem("channel", "event://*/deki/pages/revert")
                     .Elem("channel", "event://*/deki/pages/rated")
                     .Elem("channel", "event://*/deki/pages/createalias")
                     .Elem("channel", "event://*/deki/pages/tags/update")
                     .Elem("channel", "event://*/deki/pages/dependentschanged/properties/*")
                     .Elem("channel", "event://*/deki/files/noop")
                     .Elem("channel", "event://*/deki/files/create")
                     .Elem("channel", "event://*/deki/files/update")
                     .Elem("channel", "event://*/deki/files/delete")
                     .Elem("channel", "event://*/deki/files/move")
                     .Elem("channel", "event://*/deki/files/restore")
                     .Elem("channel", "event://*/deki/comments/noop")
                     .Elem("channel", "event://*/deki/comments/create")
                     .Elem("channel", "event://*/deki/comments/update")
                     .Elem("channel", "event://*/deki/comments/delete")
                     .Elem("channel", "event://*/deki/users/dependentschanged/properties/*")
                     .Elem("channel", "event://*/deki/users/create")
                     .Elem("channel", "event://*/deki/users/update")
                     .Elem("channel", "event://*/deki/users/login")
                     .Start("recipient")
                         .Attr("authtoken", _apikey)
                         .Elem("uri", Self.Uri.At("queue"))
                     .End()
                 .End();
            if(_usePersistentSubscription) {
                var locationKey = StringUtil.ComputeHashString(pubsubPlug.Uri.AsPublicUri().WithoutQuery() + InternalAccessKey);
                var accessKey = StringUtil.ComputeHashString(InternalAccessKey);
                subscriptionSet.Attr("max-failure-duration", _subscriptionMaxFailureDuration);
                pubsubPlug = pubsubPlug.WithHeader("X-Set-Access-Key", accessKey).WithHeader("X-Set-Location-Key", locationKey);
            }
            DreamMessage subscription = null;
            yield return pubsubPlug.At("subscribers").PostAsync(subscriptionSet).Set(x => subscription = x);

            // only care about created responses, but log other failures
            switch(subscription.Status) {
            case DreamStatus.Created: {
                    var accessKey = subscription.ToDocument()["access-key"].AsText;
                    var location = subscription.Headers.Location;
                    Cookies.Update(DreamCookie.NewSetCookie("access-key", accessKey, location), null);
                    _subscriptionLocation = location.AsLocalUri().WithoutQuery();
                    _log.DebugFormat("subscribed indexer for events at {0}", _subscriptionLocation);
                    break;
                }
            case DreamStatus.Conflict:
                _log.DebugFormat("didn't subscribe, since we already had a subscription in place");
                break;
            default:
                _log.WarnFormat("subscribe to {0} failed: {1}", pubsubPlug.Uri.ToString(), subscription.Status);
                break;
            }
            result.Return();
        }