Beispiel #1
0
        public static DbxObject Register(Instance instance, string type, string email, string password)
        {
            // Check email isn't already in use
            var objs = instance.LocateEq(type, Locate.GenerateSimple("email", email)); // TODO: Race condition?
            if (objs.Count > 0) throw new UserErrorException("auth.ambigious", "Invalid address, email already in use '" + email + "'");

            // Calculate auth factors
            var salt = Util.GenerateSalt(32);
            var authhash = GenerateAuthHash(email, password, salt);

            // Create object
            var properties = new Dictionary<string, object>();
            properties["email"] = email;
            properties["authhash"] = authhash;
            properties["salt"] = salt;
            return instance.Create(type, "system", properties);
        }
Beispiel #2
0
        public override DbxObject GetObject(Instance instance, string type, object rawauthdata)
        {
            DbxObject obj;
            string access_token;
            string partner = null;
            bool tos = false;

            try {
                var authdata = (Dictionary<string, object>)rawauthdata;

                // Get access_token
                access_token = (string)authdata["access_token"];

                // Try and get partneruid
                if (authdata.ContainsKey("partner")) partner = (string)authdata["partner"];

                // Try and get TOS
                if (authdata.ContainsKey("tos")) tos = (bool)authdata["tos"];
            } catch {
                throw new UserErrorException("parameter.invalid", "auth; Invalid form");
            }

            // Perform FB query
            string result;
            try {
                result = Facebook.WebGet("https://graph.facebook.com/me?fields=id,name,first_name,last_name,link,email,timezone,locale,verified,updated_time&access_token=" + Common.Util.UrlEncode(access_token));
            } catch (OAuthException) {
                throw new ObjectNotExistException();
            }

            // Convert response to objects
            var ret = new Dictionary<string, object>();
            try {
                ret = Common.Util.JsonDeserialize<Dictionary<string, object>>(result);
            } catch (Exception) {
                throw new UserErrorException("upstream", "Unexpected response from Facebook");
            }

            // Extract key values
            if (ret["id"].ToString() == "0" || ret["id"].ToString() == "") throw new UserErrorException("upstream", "Invalid FBID returned from Facebook");
            var fbid = Util.ParseNumber(ret["id"]);

            string email = "";
            if (ret.ContainsKey("email")) email = ((string)ret["email"]).ToLowerInvariant();

            // Calculate properties
            var props = new Dictionary<string, object>();
            props["email"] = email;
            props["fbid"] = fbid;
            props["creatorModule"] = "auth";
            if (ret.ContainsKey("name")) props["dname"] = ret["name"];
            if (ret.ContainsKey("name")) props["aname"] = ret["name"];
            if (ret.ContainsKey("fbLink")) props["fbLink"] = ret["link"];
            if (ret.ContainsKey("fbTimezone")) props["fbTimezone"] = ret["timezone"];
            if (ret.ContainsKey("fbLocale")) props["fbLocale"] = ret["locale"];
            if (ret.ContainsKey("fbVerified")) props["fbVerified"] = ret["verified"];
            if (ret.ContainsKey("fbUpdated")) props["fbUpdated"] = ret["updated_time"];
            if (tos) props["tos"] = true;

            if (null != partner) {
                // Check object exists
                try {
                    obj = instance.Uid("partner$" + partner);
                } catch (ObjectNotExistException) {
                    throw new UserErrorException("parameter.invalid", "Invalid partner reference in 'partner'");
                }

                // Set property
                props["partner"] = "partner$" + partner;
            }

            // Plan A: Try search by ID
            var objs = instance.LocateEq("user", Locate.GenerateSimple("fbid", fbid));

            if (objs.Count == 0) {
                // User not found, create

                obj = instance.Create("user", "system", props);
            } else {
                // User found, update

                // Find oldest record (HACK: To handle ambigious matches)
                obj = objs[0];
                foreach (var item in objs) {
                    if (item.Predecessor > 0 && item.Predecessor < obj.Predecessor) obj = item;
                };

                obj = obj.GetWritableInstance();
                obj.Set(props, "system");
            }

            // Enforce TOS
            if (!((bool)obj.GetProp("tos", "system"))) throw new UserErrorException("auth.prerequisite.tos", "Terms of Service has not yet been accepted");

            return obj;
        }