internal TokenCredentials(Stream json, string database)
        {
            Database = database;
            using (var reader = new Json.Embed.JsonTextReader(json))
            {
                foreach (var kvp in reader.Flatten())
                {
                    switch (kvp.Key)
                    {
                    case "$.access_token":
                        AccessToken = kvp.Value.ToString();
                        break;

                    case "$.token_type":
                        TokenType = kvp.Value.ToString();
                        break;

                    case "$.expires_in":
                        Expires = DateTime.UtcNow.AddSeconds((int)kvp.Value);
                        break;
                    }
                }
            }

            if (string.IsNullOrEmpty(AccessToken))
            {
                throw new InvalidOperationException("An access token must be specified.");
            }

            InitAccessToken();
        }
Пример #2
0
 private List <KeyValuePair <string, object> > Flatten(string json)
 {
     using (var reader = new StringReader(json))
         using (var jReader = new Json.Embed.JsonTextReader(reader))
         {
             return(jReader.Flatten().ToList());
         }
 }
Пример #3
0
        public OAuthConfig(string json, Uri baseUri)
        {
            AuthorizeEndpoint = new Uri(baseUri, "connect/authorize");
            TokenEndpoint     = new Uri(baseUri, "connect/token");

            using (var reader = new Json.Embed.JsonTextReader(json))
            {
                foreach (var kvp in reader.Flatten())
                {
                    switch (kvp.Key)
                    {
                    case "$.authorization_endpoint":
                        //AuthorizeEndpoint = new Uri(kvp.Value.ToString());
                        break;

                    case "$.token_endpoint":
                        //TokenEndpoint = new Uri(kvp.Value.ToString());
                        break;

                    case "$.protocol_info.protocol_type":
                        if (string.Equals(kvp.Value?.ToString(), "Standard", StringComparison.OrdinalIgnoreCase))
                        {
                            ProtocolType = ProtocolType.Standard;
                        }
                        else
                        {
                            ProtocolType = ProtocolType.Custom;
                        }
                        break;

                    case "$.protocol_version":
#if NET35
                        try
                        {
                            ProtocolVersion = new Version(kvp.Value?.ToString());
                        }
                        catch (Exception)
                        {
                            ProtocolVersion = new Version(0, 0);
                        }
#else
                        if (Version.TryParse(kvp.Value?.ToString(), out var version))
                        {
                            ProtocolVersion = version;
                        }
                        else
                        {
                            ProtocolVersion = new Version(0, 0);
                        }
#endif
                        break;
                    }
                }
            }
        }
        private void InitAccessToken()
        {
            var parts = AccessToken.Split('.');

            if (parts.Length < 2)
            {
                throw new ArgumentException("Invalid JWT token");
            }

            var body = parts[1];

            body = body.Replace('-', '+').Replace('_', '/');
            var diff = body.Length % 4;

            if (diff > 0)
            {
                body += new string('=', 4 - diff);
            }

            var bytes    = Convert.FromBase64String(body);
            var jsonBody = Encoding.UTF8.GetString(bytes, 0, bytes.Length);

            using (var reader = new Json.Embed.JsonTextReader(jsonBody))
            {
                foreach (var kvp in reader.Flatten())
                {
                    switch (kvp.Key)
                    {
                    case "$.exp":
                        Expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds((int)kvp.Value);
                        break;

                    case "$.database":
                        Database = kvp.Value?.ToString() ?? Database;
                        break;

                    case "$.username":
                        Username = kvp.Value?.ToString();
                        break;
                    }
                }
            }
        }
Пример #5
0
        private static TocNode InitCui(XmlReader reader)
        {
            var elementNames = new Stack <string>();

            elementNames.Push(reader.GetAttribute("type"));
            var curr = new TocNode()
            {
                _type = reader.GetAttribute("type"),
                _id   = reader.GetAttribute("id")
            };
            var allNodes = new Dictionary <string, TocNode>();

            allNodes[curr._id] = curr;

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.Element:
                    if (reader.LocalName == "Item")
                    {
                        elementNames.Push(reader.GetAttribute("type"));
                    }
                    else
                    {
                        elementNames.Push(reader.LocalName);
                    }
                    if (reader.LocalName == "Item")
                    {
                        curr = new TocNode()
                        {
                            _type = reader.GetAttribute("type"),
                            _id   = reader.GetAttribute("id")
                        };
                        allNodes[curr._id] = curr;
                    }
                    break;

                case XmlNodeType.EndElement:
                    if (elementNames.Count > 0)
                    {
                        elementNames.Pop();
                    }
                    break;

                case XmlNodeType.Text:
                case XmlNodeType.CDATA:
                    if (!string.IsNullOrEmpty(reader.Value))
                    {
                        switch (elementNames.Peek())
                        {
                        case "id":
                        case "itemtype":
                        case "section":
                            break; // Do nothing

                        case "image":
                            curr.Image = reader.Value;
                            break;

                        case "name":
                            curr.Name = reader.Value;
                            break;

                        case "label":
                            curr.Label = reader.Value;
                            break;

                        case "sort_order":
                            curr.SortOrder = int.Parse(reader.Value);
                            break;

                        case "additional_data":
                            using (var json = new Json.Embed.JsonTextReader(reader.Value))
                            {
                                foreach (var kvp in json.Flatten())
                                {
                                    switch (kvp.Key)
                                    {
                                    case "$.itemTypeId":
                                        curr._references.Add(new ItemRef("ItemType", kvp.Value?.ToString()));
                                        break;

                                    case "$.tocViewId":
                                        curr._references.Add(new ItemRef("TOC View", kvp.Value?.ToString()));
                                        break;

                                    case "$.tocAccessId":
                                    case "$.relatedTocAccessId":
                                        curr._references.Add(new ItemRef("TOC Access", kvp.Value?.ToString()));
                                        break;

                                    case "$.formId":
                                        curr._references.Add(new ItemRef("Form", kvp.Value?.ToString()));
                                        break;

                                    default:
                                        if (kvp.Value != null)
                                        {
                                            curr.AdditionalData[kvp.Key.Substring(2)] = kvp.Value;
                                        }
                                        break;
                                    }
                                }
                            }
                            break;

                        default:
                            curr.AdditionalData[elementNames.Peek()] = reader.Value;
                            break;
                        }
                    }
                    break;
                }
            }

            var root = new TocNode();

            foreach (var node in allNodes.Values)
            {
                if (node.AdditionalData.TryGetValue("parent_menu", out var parentId) &&
                    !string.IsNullOrEmpty(parentId?.ToString()) &&
                    allNodes.TryGetValue(parentId?.ToString(), out var parent))
                {
                    parent._children.Add(node);
                    node.AdditionalData.Remove("parent_menu");
                }
                else
                {
                    root._children.Add(node);
                }
            }

            return(root);
        }
Пример #6
0
        private IPromise <TokenCredentials> GetCredentials(bool async)
        {
            var req = new HttpRequest
            {
                Content = new SimpleContent(new Dictionary <string, string>()
                {
                    { "client_id", "IOMApp" },
                    { "grant_type", "password" },
                    { "scope", "Innovator" },
                    { "username", Uri.EscapeDataString(_hashCred.Username) },
                    { "database", Uri.EscapeDataString(_hashCred.Database) },
                    { "password", Uri.EscapeDataString(_hashCred.PasswordHash) },
                }.Select(k => k.Key + "=" + k.Value).GroupConcat("&"), "application/x-www-form-urlencoded")
            };

            req.Headers.Add("Accept", "application/json");
            var result = new Promise <TokenCredentials>();

            result.CancelTarget(
                _service.PostPromise(_config.TokenEndpoint, async, req, new LogData(4
                                                                                    , "Innovator: Get OAuth token"
                                                                                    , Factory.LogListener)
            {
                { "database", _hashCred.Database },
                { "url", _config.TokenEndpoint },
                { "user_name", _hashCred.Username },
            })
                .Convert(r => new TokenCredentials(r.AsStream, _hashCred.Database))
                .Done(result.Resolve)
                .Fail(e =>
            {
                try
                {
                    if (!(e is HttpException httpEx))
                    {
                        result.Reject(e);
                        return;
                    }
                    var faultCode   = default(string);
                    var faultstring = default(string);
                    using (var reader = new Json.Embed.JsonTextReader(httpEx.Response.AsStream))
                    {
                        foreach (var kvp in reader.Flatten())
                        {
                            switch (kvp.Key)
                            {
                            case "$.error":
                                faultCode = kvp.Value?.ToString();
                                break;

                            case "$.error_description":
                                faultstring = kvp.Value?.ToString();
                                break;
                            }
                        }
                    }

                    result.Reject(ElementFactory.Local.FromXml(@"<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:i18n='http://www.aras.com/I18N'>
  <SOAP-ENV:Body>
    <SOAP-ENV:Fault>
      <faultcode>@0</faultcode>
      <faultstring>@1</faultstring>
      <faultactor>OAuthServer</faultactor>
      <detail>unknown error</detail>
    </SOAP-ENV:Fault>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>", faultCode, faultstring).Exception);
                }
                catch (Exception ex)
                {
                    result.Reject(ex);
                }
            }));
            return(result);
        }
Пример #7
0
        public static IPromise <IAuthenticator> GetAuthenticator(Uri innovatorServerBaseUrl, HttpClient service, ICredentials creds, bool async)
        {
            var discovery = new Uri(innovatorServerBaseUrl, "OAuthServerDiscovery.aspx");
            var req       = new HttpRequest();

            req.Headers.Add("Aras-Set-HttpSessionState-Behavior", "switch_to_initial");
            var oauthBaseUri = default(Uri);

            var result = new Promise <IAuthenticator>();

            result.CancelTarget(
                service.GetPromise(discovery, async, new LogData(4
                                                                 , "Innovator: Get OAuth URL"
                                                                 , Factory.LogListener)
            {
                { "url", discovery },
            }, req)
                .Continue(r =>
            {
                if (r.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    throw new Exception("OAuth not found");
                }

                var serverUrls = default(List <Uri>);
                using (var json = new Json.Embed.JsonTextReader(r.AsStream))
                {
                    serverUrls = json.Flatten()
                                 .Where(k => k.Key.StartsWith("$.locations[") &&
                                        k.Key.EndsWith("].uri") &&
                                        k.Value is string str &&
                                        !string.IsNullOrEmpty(str))
                                 .Select(k => new Uri(k.Value.ToString()))
                                 .OrderBy(u => string.Equals(u.Host, innovatorServerBaseUrl.Host, StringComparison.OrdinalIgnoreCase) ? 0 : 1)
                                 .ToList();
                }

                if (serverUrls?.Count < 1)
                {
                    throw new InvalidOperationException("OAuth server URL could not be found");
                }

                oauthBaseUri = serverUrls[0];
                var oauthUri = new Uri(oauthBaseUri, ".well-known/openid-configuration");
                return(service.GetPromise(oauthUri, async, new LogData(4
                                                                       , "Innovator: Get OAuth Config"
                                                                       , Factory.LogListener)
                {
                    { "url", oauthUri },
                }));
            })
                .Progress(result.Notify)
                .Done(r =>
            {
                var config = new OAuthConfig(r.AsStream, oauthBaseUri);
                if (config.ProtocolVersion >= new Version("1.0"))
                {
                    result.Resolve(new OAuthAuthenticator(service, config, creds));
                }
                else
                {
                    result.Resolve(new LegacyAuthenticator(innovatorServerBaseUrl, creds));
                }
            })
                .Fail(e =>
            {
                result.Resolve(new LegacyAuthenticator(innovatorServerBaseUrl, creds));
            }));
            return(result);
        }