Esempio n. 1
0
        public RESTReplyData user_create(RESTRequestData pReq, List <string> pArgs)
        {
            // This specific endpoint only creates a user
            users_request usreq;

            try
            {
                usreq = pReq.RequestBodyObject <users_request>();
            }
            catch (Exception e)
            {
                Context.Log.Error("{0} Malformed reception: {1}", _logHeader, e.ToString());
                throw new Exception("Malformed content");
            }

            string userName  = usreq.User["username"];
            string userPW    = usreq.User["password"];
            string userEmail = usreq.User["email"];

            ResponseBody respBody = new ResponseBody();

            if (!Users.Instance.CreateAccountPW(userName, userPW, userEmail))
            {
                // If didn't create, return a fail
                respBody = new ResponseBody("fail", new Dictionary <string, string>()
                {
                    { "username", "already exists" }
                });
            }

            return(new RESTReplyData(respBody));
        }
Esempio n. 2
0
        public RESTReplyData user_activity(RESTRequestData pReq, List <string> pArgs)
        {
            RESTReplyData replyData = new RESTReplyData();  // The HTTP response info
            ResponseBody  respBody  = new ResponseBody();

            try
            {
                bodyUserActivityRequest reqBody = pReq.RequestBodyObject <bodyUserActivityRequest>();

                if (Accounts.Instance.TryGetAccountWithAuthToken(pReq.AuthToken, out AccountEntity aAccount))
                {
                    // What does an activity do?
                    Context.Log.Info("{0} Received user_activity={1} from {2}",
                                     _logHeader, reqBody.action_name, aAccount.Username);
                }
                else
                {
                    Context.Log.Info("{0} Received user_activity={1} from unknown user",
                                     _logHeader, reqBody.action_name);
                    respBody.Status  = "notfound";
                    replyData.Status = (int)HttpStatusCode.NotFound;
                }
            }
            catch
            {
                Context.Log.Error("{0} Badly formed user_activities request from {1}",
                                  _logHeader, pReq.SenderKey);
                replyData.Status = (int)HttpStatusCode.BadRequest;
            }
            replyData.SetBody(respBody, pReq);
            return(replyData);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        private void GetAccountLocationIfSpecified(AccountEntity pAccount, RESTRequestData pReq)
        {
            try
            {
                // The 'location' information is sent only when it changes
                JObject requestBodyJSON = pReq.RequestBodyJSON();
                if (requestBodyJSON.ContainsKey("location"))
                {
                    bodyUserHeartbeatLocation requestData = pReq.RequestBodyObject <bodyUserHeartbeatLocation>();

                    bodyHeartbeatLocationInfo loc = requestData.location;
                    pAccount.Location = new LocationInfo()
                    {
                        Connected      = loc.connected,
                        Path           = loc.path,
                        PlaceID        = loc.place_id,
                        DomainID       = loc.domain_id,
                        NetworkAddress = loc.network_address,
                        NetworkPort    = Int32.Parse(loc.network_port ?? "9400"),
                        NodeID         = loc.node_id,
                        Availability   = Enum.Parse <Discoverability>(loc.availability ?? "none", false)
                    };
                    pAccount.Updated();
                }
            }
            catch (Exception e)
            {
                Context.Log.Error("{0} GetAccountLocationIfSpecified: Exception parsing body of message. AccountID={1}. {2}",
                                  _logHeader, pAccount.AccountID, e);
                Context.Log.Error("{0} GetAccountLocationIfSpecified:     Body = {1}", _logHeader, pReq.RequestBody);
            }
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }
Esempio n. 7
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

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

            if (Domains.Instance.TryGetDomainWithID(domainID, out DomainEntity dobj))
            {
                try
                {
                    // Context.Log.Debug("{0} domain_heartbest PUT: Domain {1}, received: {2}",
                    //                     _logHeader, domainID, pReq.RequestBody);
                    bodyHeartbeatRequest requestData = pReq.RequestBodyObject <bodyHeartbeatRequest>();

                    // If there is no api_key, things aren't initialized
                    if (String.IsNullOrEmpty(dobj.API_Key))
                    {
                        replyData.Status = 401;
                    }
                    else
                    {
                        dobj.NetworkingMode = requestData.domain.automatic_networking;
                        bodyHeartbeatData dat = requestData.domain.heartbeat;
                        dobj.Protocol   = dat.protocol;
                        dobj.Restricted = dat.restricted;
                        dobj.Version    = dat.version;
                        dobj.LoggedIn   = dat.num_users;
                        dobj.Anon       = dat.num_anon_users;
                        dobj.TotalUsers = dat.num_anon_users + dat.num_users;

                        dobj.TimeOfLastHeartbeat = DateTime.UtcNow;
                        dobj.Updated();
                    }
                }
                catch (Exception e)
                {
                    Context.Log.Error("{0} domain_heartbeat: Exception parsing body: {1}", _logHeader, e.ToString());
                }
            }
            else
            {
                Context.Log.Error("{0} domain_heartbeat: unknown domain. Returning 404", _logHeader);
                replyData.Status = 404; // this will trigger a new temporary domain name
            }

            // replyData.Body = respBody; there is no body in the response
            return(replyData);
        }
Esempio n. 8
0
        public RESTReplyData user_location_set(RESTRequestData pReq, List <string> pArgs)
        {
            ResponseBody respBody = new ResponseBody();

            if (Users.Instance.TryGetUserWithAuth(pReq.AuthToken, out UserEntity aUser))
            {
                LocationPacket loc = pReq.RequestBodyObject <LocationPacket>();
                // TODO: do whatever putting the location does
            }
            else
            {
                respBody.Status = "fail";
            }
            return(new RESTReplyData(respBody));
        }
Esempio n. 9
0
        public RESTReplyData user_activity(RESTRequestData pReq, List <string> pArgs)
        {
            Heartbeat_Memory    hbmem = new Heartbeat_Memory();
            user_activity_input uai   = pReq.RequestBodyObject <user_activity_input>();
            RESTReplyData       rd    = new RESTReplyData();

            rd.Status = 404;
            rd.Body   = "{\"status\":\"notfound\"}";
            if (uai.action_name == "quit")
            {
                if (hbmem.Contains(pReq.RemoteUser.ToString()))
                {
                    hbmem.Rem(pReq.RemoteUser.ToString());
                }
                rd        = new RESTReplyData();
                rd.Status = 200;
                user_activities_reply uar = new user_activities_reply();
                uar.status = "success";
                rd.Body    = JsonConvert.SerializeObject(uar);
                Console.WriteLine("=====> user_action: quit; " + pReq.RemoteUser.ToString());
                return(rd);
            }
            return(rd);
        }
Esempio n. 10
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);
        }
Esempio n. 11
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);
        }