Example #1
0
        public RESTReplyData user_friends_post(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                bodyUserFriendsPost body = pReq.RequestBodyObject <bodyUserFriendsPost>();
                string friendname        = body.username;
                Context.Log.Debug("{0} user_friends_post: adding friend {1} for user {2}",
                                  _logHeader, body.username, aAccount.Username);
                if (Accounts.Instance.TryGetAccountWithUsername(friendname, out AccountEntity _))
                {
                    if (!aAccount.Friends.Contains(friendname))
                    {
                        aAccount.Friends.Add(friendname);
                    }
                }
                else
                {
                    Context.Log.Error("{0} user_friends_post: attempt to add friend that does not exist. Requestor={1}, friend={2}",
                                      _logHeader, aAccount.Username, friendname);
                    respBody.RespondFailure("Attempt to add friend that does not exist");
                }
            }
            else
            {
                Context.Log.Error("{0} GET user/friends requested without auth token. Token={1}",
                                  _logHeader, pReq.AuthToken);
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #2
0
        public RESTReplyData put_ice_address(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                // Context.Log.Debug("{0} domains/ice_server_addr PUT. Body={1}", _logHeader, pReq.RequestBody);
                bodyIceServerPut isr           = pReq.RequestBodyObject <bodyIceServerPut>();
                string           includeAPIKey = isr.domain.api_key;
                if (String.IsNullOrEmpty(aDomain.API_Key) || includeAPIKey == aDomain.API_Key)
                {
                    aDomain.IceServerAddr = isr.domain.ice_server_address;
                }
                else
                {
                    respBody.RespondFailure();
                    replyData.Status = 401; // not authorized
                }
            }
            else
            {
                respBody.RespondFailure();
                replyData.Status = 404;
            }
            return(replyData);
        }
Example #3
0
        public RESTReplyData put_ice_address(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                // Context.Log.Debug("{0} domains/ice_server_addr PUT. Body={1}", _logHeader, pReq.RequestBody);
                bodyIceServerPut isr           = pReq.RequestBodyObject <bodyIceServerPut>();
                string           includeAPIKey = isr.domain.api_key;
                if (VerifyDomainAccess(aDomain, pReq, includeAPIKey, out string oFailureReason))
                {
                    aDomain.IceServerAddr = isr.domain.ice_server_address;
                }
                else
                {
                    Context.Log.Error("{0} PUT domains/%/ice_server_address not authorized. DomainID={1}",
                                      _logHeader, domainID);
                    respBody.RespondFailure(oFailureReason);
                    replyData.Status = (int)HttpStatusCode.Unauthorized;
                }
            }
            else
            {
                respBody.RespondFailure("No such domain");
                replyData.Status = (int)HttpStatusCode.NotFound;
            }
            return(replyData);
        }
Example #4
0
        public RESTReplyData admin_domain_delete(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                if (aAccount.IsAdmin)
                {
                    string domainID = pArgs.Count == 1 ? pArgs[0] : null;
                    if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
                    {
                        Domains.Instance.RemoveDomain(aDomain);
                    }
                    else
                    {
                        respBody.RespondFailure("No such domain");
                    }
                }
                else
                {
                    respBody.RespondFailure("Requesting account is not an administrator");
                    replyData.Status = (int)HttpStatusCode.Unauthorized;
                }
            }
            else
            {
                respBody.RespondFailure("Authorization token not found");
                replyData.Status = (int)HttpStatusCode.Unauthorized;
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #5
0
        public RESTReplyData user_location_set(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                try
                {
                    GetAccountLocationIfSpecified(aAccount, pReq);
                }
                catch (Exception e)
                {
                    Context.Log.Error("{0} PUT user/location Failed body parsing. Acct={1}: {2}",
                                      _logHeader, aAccount.AccountID, e);
                    respBody.RespondFailure("failed location parsing", e.ToString());
                }
            }
            else
            {
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #6
0
        public RESTReplyData set_public_key(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                try
                {
                    string includedAPIKey = pReq.RequestBodyMultipart("api_key");

                    // If this is a temp domain, the supplied API key must match
                    // TODO: is there another Authorization later (ie, maybe user auth?)
                    if (String.IsNullOrEmpty(aDomain.API_Key) || aDomain.API_Key == includedAPIKey)
                    {
                        // The PUT sends the key as binary but it is later sent around
                        //    and processed as a Base64 string.
                        Stream byteStream = pReq.RequestBodyMultipartStream("public_key");
                        if (byteStream != null)
                        {
                            using var memStream = new MemoryStream();
                            byteStream.CopyTo(memStream);
                            aDomain.Public_Key = Convert.ToBase64String(memStream.ToArray());
                            aDomain.Updated();
                            // Context.Log.Debug("{0} successful set of public_key for {1}", _logHeader, domainID);
                        }
                        else
                        {
                            Context.Log.Error("{0} could not extract public key from request body: domain {1}",
                                              _logHeader, domainID);
                            replyData.Status = 401; // not authorized
                            respBody.RespondFailure();
                        }
                    }
                    else
                    {
                        Context.Log.Error("{0} attempt to set public_key with non-matching APIKeys: domain {1}",
                                          _logHeader, domainID);
                        replyData.Status = 401; // not authorized
                        respBody.RespondFailure();
                    }
                }
                catch (Exception e)
                {
                    Context.Log.Error("{0} exception parsing multi-part http: {1}", _logHeader, e.ToString());
                    respBody.RespondFailure();
                }
            }
            else
            {
                Context.Log.Error("{0} attempt to set public_key for unknown domain {1}", _logHeader, domainID);
                respBody.RespondFailure();
            }

            replyData.Body = respBody;
            return(replyData);
        }
Example #7
0
        public RESTReplyData set_public_key(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            SessionEntity aSession = Sessions.Instance.UpdateSession(pReq.SenderKey);

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                try
                {
                    string includedAPIKey = pReq.RequestBodyMultipart("api_key");
                    if (VerifyDomainAccess(aDomain, pReq, includedAPIKey, out string oFailureReason))
                    {
                        // The PUT sends the key as binary but it is later sent around
                        //    and processed as a Base64 string.
                        Stream byteStream = pReq.RequestBodyMultipartStream("public_key");
                        if (byteStream != null)
                        {
                            aDomain.Public_Key = Tools.ConvertPublicKeyStreamToBase64(byteStream);
                            aDomain.Updated();
                            // Context.Log.Debug("{0} successful set of public_key for {1}", _logHeader, domainID);
                        }
                        else
                        {
                            Context.Log.Error("{0} could not extract public key from request body: domain {1}",
                                              _logHeader, domainID);
                            replyData.Status = (int)HttpStatusCode.Unauthorized;
                            respBody.RespondFailure("Could not extract public key from request body");
                        }
                    }
                    else
                    {
                        Context.Log.Error("{0} attempt to set public_key when no authorized: domain {1}",
                                          _logHeader, domainID);
                        replyData.Status = (int)HttpStatusCode.Unauthorized;
                        respBody.RespondFailure(oFailureReason);
                    }
                }
                catch (Exception e)
                {
                    Context.Log.Error("{0} exception parsing multi-part http: {1}", _logHeader, e.ToString());
                    respBody.RespondFailure("Exception parsing multi-part http", e.ToString());
                }
            }
            else
            {
                Context.Log.Error("{0} attempt to set public_key for unknown domain {1}", _logHeader, domainID);
                respBody.RespondFailure("unknown domain");
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #8
0
        public RESTReplyData user_profile_gen(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                respBody.Data = new bodyUserProfileReply()
                {
                    user = new bodyUserProfileInfo()
                    {
                        username          = aAccount.Username,
                        accountid         = aAccount.AccountID,
                        xmpp_password     = aAccount.xmpp_password,
                        discourse_api_key = aAccount.discourse_api_key,
                        wallet_id         = aAccount.wallet_id
                    }
                };
            }
            else
            {
                Context.Log.Error("{0} GET user/profile requested without auth token. Token={1}", _logHeader, pReq.AuthToken);
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            // Context.Log.Debug("{0} GET user/profile. Response={1}", _logHeader, replyData.Body);
            return(replyData);
        }
Example #9
0
        public RESTReplyData get_public_key(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            string username = pArgs.Count == 1 ? pArgs[0] : null;

            if (Accounts.Instance.TryGetAccountWithUsername(username, out AccountEntity aAccount))
            {
                respBody.Data = new bodyUserPublicKeyReply()
                {
                    public_key = aAccount.Public_Key,
                    username   = aAccount.Username,
                    accountid  = aAccount.AccountID
                };
            }
            else
            {
                Context.Log.Error("{0} GET fetch of user public key for unknown acct. SenderKey: {1}, Username: {2}",
                                  _logHeader, pReq.SenderKey, username);
                respBody.RespondFailure("Unknown username");
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #10
0
        public RESTReplyData admin_get_accounts(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                PaginationInfo     pagination  = new PaginationInfo(pReq);
                AccountFilterInfo  acctFilter  = new AccountFilterInfo(pReq);
                AccountScopeFilter scopeFilter = new AccountScopeFilter(pReq, aAccount);

                respBody.Data = new bodyAccountsReply()
                {
                    accounts = Accounts.Instance.Enumerate(pagination, acctFilter, scopeFilter).Select(acct =>
                    {
                        return(new bodyAccountInfo(acct));
                    }).ToArray()
                };
            }
            else
            {
                Context.Log.Error("{0} GET accounts requested with bad auth", _logHeader);
                respBody.RespondFailure("Bad authorization");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #11
0
        public RESTReplyData get_public_key(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                respBody.Data = new bodyDomainPublicKeyGetResponse()
                {
                    public_key = aDomain.Public_Key
                };
            }
            else
            {
                // return nothing!
                respBody.RespondFailure();
                respBody.Data = new Dictionary <string, string>()
                {
                    { "domain", "there is no domain with that ID" }
                };
                replyData.Status = 404;
                // Context.Log.Debug("{0} get_domain GET: no domain! Returning: {1}", _logHeader, replyData.Body);
            }

            replyData.Body = respBody;  // serializes JSON
            return(replyData);
        }
Example #12
0
        public RESTReplyData get_domains(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                PaginationInfo pagination = new PaginationInfo(pReq);

                respBody.Data = new bodyDomainsReply()
                {
                    domains = Domains.Instance.Enumerate(pagination).Select(dom =>
                    {
                        return(new bodyDomainInfo(dom));
                    }).ToArray()
                };
            }
            else
            {
                respBody.RespondFailure("Unauthorized");
                replyData.Status = (int)HttpStatusCode.Unauthorized;
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #13
0
        public RESTReplyData get_public_key(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                respBody.Data = new bodyDomainPublicKeyGetResponse()
                {
                    public_key = aDomain.Public_Key
                };
            }
            else
            {
                // return nothing!
                respBody.RespondFailure("unknown domain");
                respBody.ErrorData("domain", "there is no domain with that ID");    // legacy HiFi compatibility
                replyData.Status = (int)HttpStatusCode.NotFound;
                // Context.Log.Debug("{0} get_domain GET: no domain! Returning: {1}", _logHeader, replyData.Body);
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #14
0
        public RESTReplyData get_domain(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity dobj))
            {
                respBody.Data = new bodyDomainResponse()
                {
                    domain = new bodyDomainReplyData()
                    {
                        id = domainID,
                        ice_server_address = dobj.GetIceServerAddr(),
                        name = dobj.PlaceName
                    }
                };
            }
            else
            {
                // return nothing!
                respBody.RespondFailure("No domain with that ID");
                respBody.ErrorData("domain", "there is no domain with that ID");

                replyData.Status = (int)HttpStatusCode.NotFound;
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #15
0
        /// <summary>
        /// Do an API operation where one account is operating on a targetted account.
        /// Takes all the request parameters and an operation to perfrom on the target account.
        /// The target account is specified by an accountID as the first parameter in the
        /// request URL.
        /// </summary>
        /// <remarks>
        /// The requesting account must be the target account or an administration account.
        /// </remarks>
        /// <param name="pReq"></param>
        /// <param name="pArgs"></param>
        /// <param name="pDoOp"></param>
        /// <returns></returns>
        public RESTReplyData APITargetedAccountOperation(RESTRequestData pReq, List <string> pArgs, DoOperation pDoOp)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                string otherAcct = pArgs.Count > 0 ? pArgs[0] : null;
                if (otherAcct != null)
                {
                    if (Accounts.Instance.TryGetAccountWithID(otherAcct, out AccountEntity targetAccount))
                    {
                        // either the requestor is admin or the same account
                        if (aAccount.Administrator || aAccount.AccountID == targetAccount.AccountID)
                        {
                            pDoOp(respBody, aAccount, targetAccount);
                        }
                        else
                        {
                            respBody.RespondFailure("Not account or administrator");
                            replyData.Status = (int)HttpStatusCode.Unauthorized;
                        };
                    }
                    else
                    {
                        respBody.RespondFailure("No such account");
                        replyData.Status = (int)HttpStatusCode.Unauthorized;
                    };
                }
                else
                {
                    respBody.RespondFailure("Account not included in request URL");
                }
            }
            else
            {
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #16
0
        public RESTReplyData get_location(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                // aAccount = the requesting account
                // TODO: lookup the specified user and see if requestor can see their location
                string otherAccountName = pArgs.Count == 1 ? pArgs[0] : null;
                if (!String.IsNullOrEmpty(otherAccountName))
                {
                    // Convert the %20's to spaces, etc
                    otherAccountName = HttpUtility.UrlDecode(otherAccountName);
                    if (Accounts.Instance.TryGetAccountWithUsername(otherAccountName, out AccountEntity otherAccount))
                    {
                        // Using only one field in 'bodyUser', others will be null and thus not sent
                        respBody.Data = new bodyUser()
                        {
                            location = BuildLocationInfo(aAccount)
                        };
                    }
                    else
                    {
                        respBody.RespondFailure("No such username");
                    }
                }
                else
                {
                    respBody.RespondFailure("Target account not included in URL");
                }
            }
            else
            {
                Context.Log.Error("{0} GET user/location requested without auth token. Token={1}", _logHeader, pReq.AuthToken);
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #17
0
        public RESTReplyData user_locker_get(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                respBody.Data = aAccount.AccountSettings;
            }
            else
            {
                Context.Log.Error("{0} GET user/locker requested without auth token. Token={1}", _logHeader, pReq.AuthToken);
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #18
0
        public RESTReplyData user_heartbeat(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            SessionEntity aSession = Sessions.Instance.UpdateSession(pReq.SenderKey);

            if (!String.IsNullOrEmpty(pReq.AuthToken))
            {
                // The user thinks they are logged in, update location info
                if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
                {
                    aAccount.TimeOfLastHeartbeat = DateTime.UtcNow;
                    GetAccountLocationIfSpecified(aAccount, pReq);

                    respBody.Data = new bodyUserHeartbeatResponse()
                    {
                        session_id = aSession?.SessionID
                    };
                }
                else
                {
                    // Who is this clown?
                    replyData.Status = (int)HttpStatusCode.Unauthorized;
                    respBody.RespondFailure("Unauthorized");
                    Context.Log.Error("{0} Heartbeat from account with non-matching token. Sender={1}",
                                      _logHeader, pReq.SenderKey);
                }
            }
            else
            {
                // A new heartbeat from a new place.
                // Is this a non-logged in user?
                Context.Log.Info("{0} Heartbeat from unknown sender {1}", _logHeader, pReq.SenderKey);
                respBody.Data = new bodyUserHeartbeatResponse()
                {
                    session_id = aSession?.SessionID
                };
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #19
0
        public RESTReplyData user_connections_delete(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            string connectionname = pArgs.Count == 1 ? pArgs[0] : null;

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                Context.Log.Debug("{0} user_connections_delete: removing connection {1} for user {2}",
                                  _logHeader, connectionname, aAccount.Username);
                aAccount.Friends.Remove(connectionname);
            }
            else
            {
                Context.Log.Error("{0} DELETE user/connections requested without auth token. Token={1}",
                                  _logHeader, pReq.AuthToken);
                respBody.RespondFailure("Unauthorized");
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #20
0
        public RESTReplyData get_domain(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity dobj))
            {
                respBody.Data = new bodyDomainResponse()
                {
                    domain = new bodyDomainReplyData()
                    {
                        id = domainID,
                        ice_server_address = dobj.GetIceServerAddr(),
                        name = dobj.PlaceName
                    }
                };
                replyData.Body = respBody;  // serializes JSON
                // Context.Log.Debug("{0} get_domain GET: domain{1}, returning: {2}",
                //                     _logHeader, domainID, replyData.Body);
            }
            else
            {
                // return nothing!
                respBody.RespondFailure();
                respBody.Data = new Dictionary <string, string>()
                {
                    { "domain", "there is no domain with that ID" }
                };
                replyData.Status = 404;
                replyData.Body   = respBody;
                // Context.Log.Debug("{0} get_domain GET: no domain! Returning: {1}", _logHeader, replyData.Body);
            }

            return(replyData);
        }
Example #21
0
        public RESTReplyData new_scope_token(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Sessions.Instance.ShouldBeThrottled(pReq.SenderKey, Sessions.Op.TOKEN_CREATE))
            {
                respBody.RespondFailure("Throttled");
                respBody.Data = new
                {
                    operation = "throttled"
                };
            }
            else
            {
                // Getting a token for a domain server
                if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity oAccount))
                {
                    AuthTokenInfo token = null;

                    string scope = pReq.Queries.ContainsKey("scope") ? pReq.Queries["scope"] : "owner";
                    switch (scope)
                    {
                    case "domain":
                        token = oAccount.CreateAccessToken(AuthTokenInfo.ScopeCode.domain);
                        // The domain/account association lasts longer
                        token.TokenExpirationTime = new DateTime(2999, 12, 31);
                        break;

                    case "owner":
                        token = oAccount.CreateAccessToken(AuthTokenInfo.ScopeCode.owner);
                        break;

                    default:
                        break;
                    }

                    if (token != null)
                    {
                        respBody.Data = new
                        {
                            token                    = token.Token,
                            token_id                 = token.TokenId,
                            refresh_token            = token.RefreshToken,
                            token_expiration_seconds = (int)(token.TokenExpirationTime - token.TokenCreationTime).TotalSeconds,
                            account_name             = oAccount.Username,
                            account_type             = oAccount.GetAccountType(),
                            account_id               = oAccount.AccountID
                        };
                    }
                    else
                    {
                        respBody.RespondFailure("Token could not be generated. Bad scope?");
                    }
                }
                else
                {
                    // Not a known account.
                    respBody.RespondFailure("Unknown requesting account");
                }
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #22
0
        public RESTReplyData user_create(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            if (Sessions.Instance.ShouldBeThrottled(pReq.SenderKey, Sessions.Op.ACCOUNT_CREATE))
            {
                respBody.RespondFailure("Throttled");
                respBody.ErrorData("error", "throttled");
            }
            else
            {
                try
                {
                    bodyUsersPost requestData = pReq.RequestBodyObject <bodyUsersPost>();

                    string userName     = requestData.user["username"];
                    string userPassword = requestData.user["password"];
                    string userEmail    = requestData.user["email"];

                    if (CheckUsernameFormat(userName))
                    {
                        if (CheckEmailFormat(userEmail))
                        {
                            Context.Log.Debug("{0} Creating account {1}/{2}", _logHeader, userName, userEmail);

                            AccountEntity newAcct = Accounts.Instance.CreateAccount(userName, userPassword, userEmail);
                            if (newAcct == null)
                            {
                                respBody.RespondFailure("Username already exists");
                                respBody.ErrorData("username", "already exists");   // legacy HiFi compatibility
                                Context.Log.Debug("{0} Failed acct creation. Username already exists. User={1}",
                                                  _logHeader, userName);
                            }
                            else
                            {
                                // Successful account creation
                                newAcct.IPAddrOfCreator = pReq.SenderKey;
                                newAcct.Updated();
                                Context.Log.Debug("{0} Successful acct creation. User={1}", _logHeader, userName);
                            }
                        }
                        else
                        {
                            respBody.RespondFailure("Bad format for email");
                            respBody.ErrorData("error", "bad format for email");
                        }
                    }
                    else
                    {
                        respBody.RespondFailure("Bad format for username");
                        respBody.ErrorData("error", "bad format for username");
                    }
                }
                catch (Exception e)
                {
                    replyData.Status = (int)HttpStatusCode.BadRequest;
                    Context.Log.Error("{0} Badly formed create account request. {1}", _logHeader, e);
                }
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #23
0
        public RESTReplyData domain_heartbeat(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();   // The request's "data" response info

            SessionEntity aSession = Sessions.Instance.UpdateSession(pReq.SenderKey);

            string domainID = pArgs.Count == 1 ? pArgs[0] : null;

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity aDomain))
            {
                try
                {
                    // Since the body has a lot of optional fields, we need to pick
                    //    through what's sent so we only set what was sent.
                    JObject requestData = pReq.RequestBodyJSON();
                    JObject domainStuff = (JObject)requestData["domain"];
                    string  apiKey      = (string)domainStuff["api_key"];

                    // Context.Log.Debug("{0} domain_heartbeat. Received {1}", _logHeader, pReq.RequestBody);
                    if (VerifyDomainAccess(aDomain, pReq, apiKey, out string oFailureReason))
                    {
                        Tools.SetIfSpecified <string>(domainStuff, "version", ref aDomain.Version);
                        Tools.SetIfSpecified <string>(domainStuff, "protocol", ref aDomain.Protocol);
                        Tools.SetIfSpecified <string>(domainStuff, "network_address", ref aDomain.NetworkAddr);
                        Tools.SetIfSpecified <string>(domainStuff, "automatic_networking", ref aDomain.NetworkingMode);
                        Tools.SetIfSpecified <bool>(domainStuff, "restricted", ref aDomain.Restricted);

                        Tools.SetIfSpecified <int>(domainStuff, "capacity", ref aDomain.Capacity);
                        Tools.SetIfSpecified <string>(domainStuff, "description", ref aDomain.Description);
                        Tools.SetIfSpecified <string>(domainStuff, "maturity", ref aDomain.Maturity);
                        Tools.SetIfSpecified <string>(domainStuff, "restriction", ref aDomain.Restriction);
                        JArray hosts = (JArray)domainStuff["hosts"];
                        if (hosts != null)
                        {
                            aDomain.Hosts = domainStuff["hosts"].ToObject <string[]>();
                        }
                        JArray tags = (JArray)domainStuff["tags"];
                        if (tags != null)
                        {
                            aDomain.Tags = domainStuff["tags"].ToObject <string[]>();
                        }

                        JObject heartbeat = (JObject)domainStuff["heartbeat"];
                        if (heartbeat != null)
                        {
                            Tools.SetIfSpecified <int>(heartbeat, "num_users", ref aDomain.NumUsers);
                            Tools.SetIfSpecified <int>(heartbeat, "num_anon_users", ref aDomain.AnonUsers);
                            aDomain.TotalUsers = aDomain.NumUsers + aDomain.AnonUsers;
                            // TODO: what to do with user_hostnames
                        }

                        aDomain.TimeOfLastHeartbeat = DateTime.UtcNow;
                        aDomain.LastSenderKey       = pReq.SenderKey;

                        aDomain.Updated();
                    }
                    else
                    {
                        Context.Log.Error("{0} domain_heartbeat with bad authorization. domainID={1}",
                                          _logHeader, domainID);
                        respBody.RespondFailure(oFailureReason);
                        replyData.Status = (int)HttpStatusCode.Unauthorized;
                    }
                }
                catch (Exception e)
                {
                    Context.Log.Error("{0} domain_heartbeat: Exception processing body: {1}", _logHeader, e.ToString());
                    respBody.RespondFailure("exception processing body", e.ToString());
                    replyData.Status = (int)HttpStatusCode.BadRequest;
                }
            }
            else
            {
                Context.Log.Error("{0} domain_heartbeat: unknown domain. Returning 404", _logHeader);
                respBody.RespondFailure("no such domain");
                replyData.Status = (int)HttpStatusCode.NotFound; // this will trigger a new temporary domain name
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #24
0
        public RESTReplyData set_public_key(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            string includedAPIKey    = null;
            string includedPublicKey = null;
            bool   parsed            = false; // whether multipart was parsed

            try
            {
                // The PUT sends the key as binary but it is later sent around
                //    and processed as a Base64 string.
                Stream byteStream = pReq.RequestBodyMultipartStream("public_key");
                if (byteStream != null)
                {
                    includedPublicKey = Tools.ConvertPublicKeyStreamToBase64(byteStream);
                    // There might has been an APIKey
                    includedAPIKey = pReq.RequestBodyMultipart("api_key");
                    parsed         = true;
                }
                else
                {
                    Context.Log.Error("{0} could not extract public key from request body in PUT user/public_key", _logHeader);
                }
            }
            catch (Exception e)
            {
                Context.Log.Error("{0} exception parsing multi-part http: {1}", _logHeader, e.ToString());
                parsed = false;
            }

            if (parsed)
            {
                // If there is account authorization in the header, set the account public key.
                // If no account authorization (the client is not logged in), check for matching
                //     APIkey and then set the session public key.
                if (String.IsNullOrEmpty(pReq.AuthToken))
                {
                    if (includedAPIKey != null &&
                        Domains.Instance.TryGetDomainWithAPIKey(includedAPIKey, out DomainEntity aDomain))
                    {
                        aDomain.Public_Key = includedPublicKey;
                    }
                    else
                    {
                        Context.Log.Error("{0} PUT user/set_public_key requested without APIKey. APIKey={1}",
                                          _logHeader, includedAPIKey);
                        respBody.RespondFailure("APIkey does not work");
                        replyData.Status = (int)HttpStatusCode.Unauthorized;
                    }
                }
                else
                {
                    if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
                    {
                        aAccount.Public_Key = includedPublicKey;
                    }
                    else
                    {
                        Context.Log.Error("{0} PUT user/set_public_key requested but could not find acct. Token={1}",
                                          _logHeader, pReq.AuthToken);
                        respBody.RespondFailure("AuthToken unauthorized");
                        replyData.Status = (int)HttpStatusCode.Unauthorized;
                    }
                }
            }
            else
            {
                Context.Log.Error("{0} PUT user/set_public_key failure parsing", _logHeader);
                respBody.RespondFailure("Multi-part body failed parsing");
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Example #25
0
        public RESTReplyData user_connections_request_post(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
            {
                bodyUserConnectionRequestPost request = pReq.RequestBodyObject <bodyUserConnectionRequestPost>();
                // The script looks for two types of 'connection' responses.
                //    If is sees data.connection == "pending", it trys again and eventually times out
                //    If data.connection has an object, it uses 'new_connection' and 'username'

                // Connection handles are the in-world nodeId's
                string thisNode  = request.user_connection_request.node_id;
                string otherNode = request.user_connection_request.proposed_node_id;

                // BEGIN sanity check DEBUG DEBUG
                {
                    // Connections use node id's to identify the two avatars, I guess because, the
                    //    world does not have access to the account identity.
                    // This debugging code prints out whether the passed nodeIds match the loction
                    //    nodeIds that we have to verify that the connection nodeIds are really the
                    //    same ones as passed in the location.
                    // All this debugging output can go away once nodeId usage is understood.
                    Context.Log.Debug("{0} connection_request: request from account '{1}' node={2}, proposed={3}",
                                      _logHeader, aAccount.Username, thisNode, otherNode);
                    if (aAccount.Location != null)
                    {
                        if (aAccount.Location.NodeID == thisNode)
                        {
                            Context.Log.Debug("{0} connection_request: request from account '{1}' and Location.NodeId matches main node",
                                              _logHeader, aAccount.Username);
                        }
                        else
                        {
                            if (aAccount.Location.NodeID == otherNode)
                            {
                                Context.Log.Debug("{0} connection_request: request from account '{1}' and Location.NodeId matches proposed node",
                                                  _logHeader, aAccount.Username);
                            }
                            else
                            {
                                Context.Log.Debug("{0} connection_request: request from account '{1}' and Location.NodeId does not match either nodes",
                                                  _logHeader, aAccount.Username);
                            }
                        }
                    }
                    else
                    {
                        Context.Log.Debug("{0} connection_request: request from account '{1}' and no location info",
                                          _logHeader, aAccount.Username);
                    }
                }
                // END sanity check DEBUG DEBUG
                try
                {
                    // This returns all the RequestConnection's that have my ID in them
                    RequestConnection previousAsk = RequestConnection.GetNodeRequests(thisNode)
                                                    // Find the ones that have me and the other requestor
                                                    .Where(req =>
                    {
                        return((req.Body.node_id == thisNode && req.Body.proposed_node_id == otherNode) ||
                               (req.Body.node_id == otherNode && req.Body.proposed_node_id == thisNode));
                        // Pick the one (there should be only one)
                    }).FirstOrDefault();

                    if (previousAsk != null)
                    {
                        Context.Log.Debug("{0} connection_request: existing request found", _logHeader);
                        // We have a pending connection request for this person
                        // Mark myself as accepting
                        if (previousAsk.Body.node_id == thisNode)
                        {
                            if (!previousAsk.Body.node_accepted)
                            {
                                previousAsk.Body.node_accepted = true;
                                previousAsk.Updated();
                            }
                        }
                        else
                        {
                            if (!previousAsk.Body.proposed_node_accepted)
                            {
                                previousAsk.Body.proposed_node_accepted = true;
                                previousAsk.Updated();
                            }
                            // I'm in the 'proposed node' position.
                            // Straighten out the node variables for simplier logic after this
                            var tmp = otherNode;
                            otherNode = thisNode;
                            thisNode  = tmp;    // after this, "thisNode" is always this account
                            Context.Log.Debug("{0} connection_request: found request was from other account", _logHeader);
                        }
                        // If both accepted, the connection is complete
                        if (previousAsk.Body.node_accepted && previousAsk.Body.proposed_node_accepted)
                        {
                            if (Accounts.Instance.TryGetAccountWithNodeId(otherNode, out AccountEntity oOtherAccount))
                            {
                                aAccount.AddConnection(oOtherAccount);
                                aAccount.Updated();
                                oOtherAccount.AddConnection(aAccount);
                                oOtherAccount.Updated();
                                respBody.Data = new
                                {
                                    connection = new
                                    {
                                        new_connection = true,      // says whether a new or pre-existing connection
                                        username       = oOtherAccount.Username
                                    }
                                };
                            }
                            else
                            {
                                // Can't find the other account... shouldn't happen
                                respBody.RespondFailure("Both agreed but cannot find other account entity");
                            }
                        }
                        else
                        {
                            // Both haven't accepted so tell the requestor that the request is pending
                            respBody.Data = new Dictionary <string, string>()
                            {
                                { "connection", "pending" }
                            };
                        }
                    }
                    else
                    {
                        // There was no previous ask so create the request.
                        Context.Log.Debug("{0} connection_request: creating connection request from '{1}",
                                          _logHeader, aAccount.Username);
                        RequestConnection newReq = new RequestConnection();
                        newReq.Body.node_id             = thisNode;
                        newReq.Body.requestor_accountId = aAccount.AccountID;
                        newReq.Body.proposed_node_id    = otherNode;
                        newReq.Body.node_accepted       = true;
                        newReq.ExpireIn(TimeSpan.FromSeconds(Context.Params.P <int>(AppParams.P_CONNECTION_REQUEST_SECONDS)));
                        newReq.AddAndUpdate();

                        // Both haven't accepted so tell the requestor that the request is pending
                        respBody.Data = new Dictionary <string, string>()
                        {
                            { "connection", "pending" }
                        };
                    }
                }
                catch
                {
                }
            }
            else
            {
                Context.Log.Error("{0} POST user/connection_request for unauthorized user. Token={1}",
                                  _logHeader, pReq.AuthToken);
                respBody.RespondFailure("Unauthorized");
            }

            replyData.SetBody(respBody, pReq);
            return(replyData);
        }