示例#1
0
        public AdminModule() : base("/admin")
        {
            this.RequiresClaims("admin");

            Get["/person", true] = async(parameters, ct) =>
            {
                var persons = await DataConnection.Ask(x => x.GetPersonsAsync());

                return(View["admin-person.cshtml", persons]);
            };

            Get["/sensor", true] = async(parameters, ct) =>
            {
                var items = await DataConnection.Ask(dc => dc.GetSensorTagsPairsAsync());

                return(View["admin-sensor.cshtml", items]);
            };

            Get["/location", true] = async(parameters, ct) =>
            {
                var locations = await DataConnection.Ask(x => x.GetLocationsAsync());

                return(View["admin-location.cshtml", locations]);
            };
        }
        private async Task <dynamic> CompareGraph(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();
            var locations = await DataConnection.Ask(x => x.GetLocationsForPersonAsync(CurrentUserGuid()));

            var items = new DashboardType(
                new List <Tuple <Location, IEnumerable <string>, List <Tuple <Sensor, IEnumerable <string> > > > >(),
                CurrentUserGuid().ToString());

            foreach (var location in locations)
            {
                var sensors = await DataConnection.Ask(x => x.GetSensorsAtLocationAsync(location));

                var taggedSensors = new List <Tuple <Sensor, IEnumerable <string> > >();

                foreach (var sensor in sensors)
                {
                    taggedSensors.Add(new Tuple <Sensor, IEnumerable <string> >(sensor, await DataConnection.Ask(x => x.GetSensorTagsAsync(sensor.Id))));
                }

                IEnumerable <string> tags = await DataConnection.Ask(x => x.GetTagsAtLocationAsync(location));

                items.Item1.Add(new Tuple <Location, IEnumerable <string>, List <Tuple <Sensor, IEnumerable <string> > > >(location, tags, taggedSensors));
            }

            return(View["compare-graph.cshtml", items]);
        }
        private async Task <dynamic> GetPerson(dynamic parameters, CancellationToken ct)
        {
            var persons = await DataConnection.Ask(x => x.GetPersonsAsync());

            var items = new List <Tuple <Person, FriendsState> >();

            if (Context.CurrentUser.IsAuthenticated())
            {
                Person currentUser = await DataConnection.Ask(x => x.GetPersonByUsernameAsync(Context.CurrentUser.UserName));

                foreach (var person in persons)
                {
                    var state = await DataConnection.Ask(x => x.GetFriendsState(currentUser.Guid, person.Guid));

                    items.Add(Tuple.Create(person, state));
                }
            }
            else
            {
                foreach (var person in persons)
                {
                    items.Add(Tuple.Create(person, FriendsState.None));
                }
            }
            return(View["person.cshtml", items]);
        }
        private async Task <dynamic> GetEditProfile(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();

            Person currentUser = await DataConnection.Ask(x => x.GetPersonByUsernameAsync(Context.CurrentUser.UserName));

            return(View["edit-person.cshtml", currentUser]);
        }
        private async Task <dynamic> getCluster(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();

            IEnumerable <Location> Locations = await DataConnection.Ask(x => x.GetLocationsForPersonAsync(CurrentUserGuid()));

            return(View["cluster.cshtml", Locations]);
        }
        private async Task <dynamic> GetAddSensor(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();

            var locations = await DataConnection.Ask(x => x.GetLocationsAsync());

            ViewBag.HighlightedLocationId = parameters.id;
            return(View["add-sensor.cshtml", locations]);
        }
        private async Task <dynamic> GetAddTag(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();

            var sensor = await DataConnection.Ask(x => x.GetSensorByIdAsync((int)parameters.id));

            var tags = await DataConnection.Ask(x => x.GetSensorTagsAsync((int)parameters.id));

            return(View["add-tag.cshtml", new Tuple <Sensor, IEnumerable <string> >(sensor, tags)]);
        }
        private async Task <dynamic> PostDashboard(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();
            var obj = JsonConvert.DeserializeObject <GraphData>(Request.Body.AsString());
            await DataConnection.Ask(dc =>
            {
                return(dc.InsertGraphAsync(obj));
            });

            return(HttpStatusCode.OK);
        }
        private async Task <dynamic> GetAddHasLocation(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();

            // First, acquire all locations.
            var newLocations = new HashSet <Location>(await DataConnection.Ask(dc => dc.GetLocationsAsync()));

            // Then remove all locations that were already assigned to the person.
            newLocations.ExceptWith(await DataConnection.Ask(dc => dc.GetLocationsForPersonAsync(CurrentUserGuid())));
            return(View["add-has-location.cshtml", newLocations]);
        }
        private async Task <dynamic> UpdateProfile(dynamic parameters, CancellationToken ct)
        {
            ViewBag.Success = "";
            ViewBag.Error   = "";

            string   name              = FormHelpers.GetString(Request.Form, "personname");
            string   newPassword       = FormHelpers.GetRawString(Request.Form, "personnewpassword");
            string   repeatNewPassword = FormHelpers.GetRawString(Request.Form, "personnewpasswordrepeat");
            string   address           = FormHelpers.GetString(Request.Form, "personaddress");
            DateTime?birthdate         = FormHelpers.GetDate(Request.Form, "personbirthdate");
            string   city              = FormHelpers.GetString(Request.Form, "personcity");
            string   zipcode           = FormHelpers.GetString(Request.Form, "personzipcode");
            string   password          = FormHelpers.GetRawString(Request.Form, "personpassword");

            bool updatePassword = !string.IsNullOrWhiteSpace(newPassword);

            Person person = await DataConnection.Ask(x => x.GetPersonByUsernameAsync(Context.CurrentUser.UserName));

            if (password != person.Data.Password)
            {
                ViewBag.Error = TextResources.PasswordMismatchError;
            }
            else if (string.IsNullOrWhiteSpace(name))
            {
                ViewBag.Error = TextResources.EmptyNameError;
            }
            else if (updatePassword && (newPassword != repeatNewPassword))
            {
                ViewBag.Error = TextResources.PasswordMismatchError;
            }
            else if (!birthdate.HasValue)
            {
                ViewBag.Error = TextResources.BadlyFormattedBirthDateError;
            }
            else
            {
                ViewBag.Success = TextResources.ProfileEditSuccess;

                await DataConnection.Ask(async dc =>
                                         await dc.UpdatePersonAsync(
                                             new Person(person.Guid,
                                                        new PersonData(
                                                            person.Data.UserName,
                                                            updatePassword ? newPassword : person.Data.Password,
                                                            name, birthdate.Value, address, city, zipcode, person.Data.IsAdministrator
                                                            )
                                                        )
                                             )
                                         );
            }

            return(await GetEditProfile(parameters, ct));
        }
        private async Task <dynamic> PostAddLocation(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();
            ViewBag.Error   = "";
            ViewBag.Success = "";

            if (!Context.CurrentUser.IsAuthenticated())
            {
                ViewBag.Error = TextResources.AddLocationNotAuthenticatedText;
            }
            else
            {
                // DataConnection.Ask is used here, because it conveniently wraps everything in
                // a single transaction.
                await DataConnection.Ask(async dc =>
                {
                    var sender = await dc.GetPersonByUsernameAsync(Context.CurrentUser.UserName);
                    if (sender == null)
                    {
                        ViewBag.Error = TextResources.UserNameNotFoundError;
                    }
                    else
                    {
                        // Retrieve the requested location name, and trim whitespace on both sides.
                        string name = FormHelpers.GetString(Request.Form, "locationname");
                        if (string.IsNullOrWhiteSpace(name))
                        {
                            // Don't create locations with empty names.
                            ViewBag.Error = TextResources.EmptyNameError;
                        }
                        else
                        {
                            var loc = await dc.GetLocationByNameAsync(name);
                            if (loc != null)
                            {
                                ViewBag.Error = string.Format(TextResources.LocationAlreadyExistsError, name);
                            }
                            else
                            {
                                await dc.InsertLocationAsync(new LocationData(name, sender.Guid, null));
                                var newLoc = await dc.GetLocationByNameAsync(name);
                                await dc.InsertHasLocationPairAsync(new PersonLocationPair(sender.Guid, newLoc.Id));
                                ViewBag.Success = TextResources.AddedLocationMessage;
                            }
                        }
                    }
                });
            }

            return(await GetAddLocation(parameters, ct));
        }
示例#12
0
        protected Func <dynamic, CancellationToken, Task <dynamic> > Recieve <T, TParam>(
            Func <TParam, T, DataConnection, Task> operation)
        {
            return(async(arg, ct) =>
            {
                var a = (TParam)arg;
                using (var textReader = new StreamReader(Request.Body))
                {
                    string data = await textReader.ReadToEndAsync();

                    var item = JsonConvert.DeserializeObject <T>(data);
                    await DataConnection.Ask(dc => operation(a, item, dc));

                    return HttpStatusCode.Created;
                }
            });
        }
#pragma warning restore 1998

        private async Task <dynamic> GetFriends(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();
            var sent = await DataConnection.Ask(x => x.GetSentFriendRequestsAsync(CurrentUserGuid()));

            var received = await DataConnection.Ask(x => x.GetRecievedFriendRequestsAsync(CurrentUserGuid()));

            var friends = await DataConnection.Ask(x => x.GetFriendsAsync(CurrentUserGuid()));

            var model = new Dictionary <FriendsState, IEnumerable <Person> >
            {
                [FriendsState.FriendRequestSent]     = sent,
                [FriendsState.FriendRequestRecieved] = received,
                [FriendsState.Friends] = friends
            };

            return(View["friends.cshtml", model]);
        }
示例#14
0
        // Operation types:
        //
        //   ApiGet, ApiPost : (Path, (Params, Connection) → Task<T>) → Handler

        /// <summary>
        /// Turn an operation on a parameter list and a data connection (which
        /// queries a value of type <typeparamref name="T"/> from the database)
        /// into an async API route handler that performs this operation and
        /// responds with query result serialized as a JSON object.
        /// </summary>
        /// <typeparam name="T">The query's result type.</typeparam>
        /// <param name="operation">The operation to wrap around.</param>
        /// <returns>A route handler.</returns>
        public static Func <dynamic, CancellationToken, Task <dynamic> > Ask <T>(
            Func <dynamic, DataConnection, Task <T> > operation,
            string JournalMode = "MEMORY", string Synchronous = "NORMAL")
        {
            return(async(parameters, ct) =>
            {
                T result = await DataConnection.Ask <T>(
                    dc => operation(parameters, dc), JournalMode, Synchronous);

                var json = JsonConvert.SerializeObject(result);

                var statusCode = result == null
                    ? HttpStatusCode.NotFound
                    : HttpStatusCode.Accepted;

                Response response = json;
                response.ContentType = "application/json";
                response.StatusCode = statusCode;
                return response;
            });
        }
        private async Task <dynamic> GetSensors(dynamic parameters, CancellationToken ct)
        {
            this.RequiresAuthentication();
            var locations = await DataConnection.Ask(x => x.GetLocationsForPersonAsync(CurrentUserGuid()));

            var items = new List <Tuple <Location, List <Tuple <Sensor, IEnumerable <string> > > > >();

            foreach (var location in locations)
            {
                var sensors = await DataConnection.Ask(x => x.GetSensorsAtLocationAsync(location));

                var taggedSensors = new List <Tuple <Sensor, IEnumerable <string> > >();
                foreach (var sensor in sensors)
                {
                    taggedSensors.Add(new Tuple <Sensor, IEnumerable <string> >(sensor, await DataConnection.Ask(x => x.GetSensorTagsAsync(sensor.Id))));
                }
                items.Add(new Tuple <Location, List <Tuple <Sensor, IEnumerable <string> > > >(location, taggedSensors));
            }

            return(View["sensor.cshtml", items]);
        }
示例#16
0
 public bool FindUser(string userName, string password, out UserIdentity userIdentity)
 {
     userIdentity = DataConnection.Ask(dc => dc.GetUserIdentityAsync(userName, password)).Result;
     return(userIdentity != null);
 }
        public SmartHomeWebModule(IFindUserMapper userMapper)
        {
            UserMapper = userMapper;

            // StaticConfiguration.EnableHeadRouting = true;

            Before += ctx =>
            {
                TextResources.Culture = (CultureInfo)this.Request.Session["CurrentCulture"];
                return(null);
            };

            Get["/"] = parameters =>
                       Context.CurrentUser.IsAuthenticated()
                    ? Response.AsRedirect("/newsfeed")
                    : (dynamic)View["home.cshtml"];

            // Pages for individual tables
            Get["/person", true] = GetPerson;

            Post["/person", true] = async(parameters, ct) =>
            {
                this.RequiresAuthentication();
                await FriendRequest(FormHelpers.GetString(Request.Form, "friendname"));

                return(await GetPerson(parameters, ct));
            };

            Get["/person/{username}", true] = GetProfile;

            Post["/person/{username}", true] = async(parameters, ct) =>
            {
                this.RequiresAuthentication();
                await FriendRequest(FormHelpers.GetString(Request.Form, "friendname"));

                return(await GetProfile(parameters, ct));
            };

            Get["/editprofile", true] = GetEditProfile;

            Post["/editprofile", true] = UpdateProfile;

            Get["/person/{username}/wall", true] = GetWall;

            Post["/person/{username}/wall", true] = PostWall;

            Get["/location", true] = async(parameters, ct) =>
            {
                var locations = await DataConnection.Ask(x => x.GetLocationsAndOwnerNamesAsync());

                return(View["location.cshtml", locations]);
            };
            Get["/message", true] = GetMessage;

            Post["/message", true] = PostMessage;

            Get["/friends", true] = GetFriends;

            Post["/friends", true] = PostFriends;

            Get["/friend-request"] = _ => Response.AsRedirect("/friends");

            Post["/friend-request", true] = async(parameters, ct) =>
            {
                this.RequiresAuthentication();
                await FriendRequest(FormHelpers.GetString(Request.Form, "friendname"));

                // TODO: this is a hack. Maybe make which success message to display a parameter of FriendRequest().
                if (!string.IsNullOrEmpty(ViewBag.Success))
                {
                    ViewBag.Success = TextResources.FriendRequestAccepted;
                }

                return(await GetFriends(parameters, ct));
            };

            Get["/sensor", true] = GetSensors;

            Get["/add-sensor/{id?}", true] = GetAddSensor;

            Post["/add-sensor/{id?}", true] = PostAddSensor;

            Get["/edit-sensor/{id}", true] = async(parameters, ct) =>
            {
                this.RequiresAuthentication();
                Sensor calledsensor = await DataConnection.Ask(x => x.GetSensorByIdAsync((int)parameters["id"]));

                return(View["edit-sensor.cshtml", calledsensor]);
            };

            Post["/edit-sensor/{id}", true] = async(parameters, ct) =>
            {
                ViewBag.Success = "";
                ViewBag.Error   = "";

                this.RequiresAuthentication();
                string name        = FormHelpers.GetString(Request.Form, "sensortitle");
                string description = FormHelpers.GetRawString(Request.Form, "descriptiontitle");
                string notes       = FormHelpers.GetRawString(Request.Form, "notestitle");

                Sensor original = await DataConnection.Ask(x => x.GetSensorByIdAsync((int)parameters["id"]));

                SensorData updatebis = new SensorData(name, description, notes, original.Data.LocationId);
                Sensor     update    = new Sensor(original.Id, updatebis);

                await DataConnection.Ask(x => x.UpdateSensorAsync(update));

                ViewBag.Success = TextResources.EditedSensorSuccess;

                return(View["edit-sensor.cshtml", update]);
            };

            Get["/edit-location/{id}", true] = async(parameters, ct) =>
            {
                this.RequiresAuthentication();
                int id  = (int)parameters["id"];
                var loc = await DataConnection.Ask(x => x.GetLocationByIdAsync(id));

                if (loc == null)
                {
                    ViewBag.Error = TextResources.LocationDoesNotExist;
                    loc           = new Location(id, new LocationData("", default(Guid), null));
                }
                return(View["edit-location.cshtml", loc]);
            };

            Post["/edit-location/{id}", true] = async(parameters, ct) =>
            {
                ViewBag.Success = "";
                ViewBag.Error   = "";

                this.RequiresAuthentication();

                int    id           = parameters["id"];
                string name         = FormHelpers.GetString(Request.Form, "locationname");
                string elecPriceStr = FormHelpers.GetString(Request.Form, "electricityprice");
                double?elecPrice    = FormHelpers.ParseDoubleOrNull(elecPriceStr);

                var update = await DataConnection.Ask(async dc =>
                {
                    // Retrieve the location that is being edited.
                    var editLoc = await dc.GetLocationByIdAsync(id);
                    if (editLoc == null)
                    {
                        ViewBag.Error = TextResources.LocationDoesNotExist;
                        return(new Location(id, new LocationData(name, default(Guid), elecPrice)));
                    }

                    var newLoc = new Location(id, new LocationData(name, editLoc.Data.OwnerGuid, elecPrice));

                    if (string.IsNullOrWhiteSpace(name))
                    {
                        // Empty names are silly, and we don't allow them.
                        ViewBag.Error = TextResources.EmptyNameError;
                    }
                    else if (name != editLoc.Data.Name && await dc.GetLocationByNameAsync(name) != null)
                    {
                        // Whoops. Name already exists.
                        ViewBag.Error = string.Format(TextResources.LocationAlreadyExistsError, name);
                    }
                    else if (!string.IsNullOrWhiteSpace(elecPriceStr) && elecPrice == null)
                    {
                        // Couldn't parse electricity price.
                        ViewBag.Error = string.Format(TextResources.ElectricityPriceParseError, elecPriceStr);
                    }
                    else
                    {
                        ViewBag.Success = TextResources.EditLocationSuccess;
                        await dc.UpdateLocationAsync(newLoc);
                    }
                    return(newLoc);
                });

                return(View["edit-location.cshtml", update]);
            };

            Get["/add-tag/{id}", true] = GetAddTag;

            Post["/add-tag/{id}", true] = PostAddTag;

            Get["/measurement", true] = async(parameters, ct) =>
            {
                var measurements = await DataConnection.Ask(x => x.GetRawMeasurementsAsync());

                return(View["measurement.cshtml", measurements]);
            };

            Get["/login"] = _ => View["login.cshtml"];

            Post["/login"] = parameter =>
            {
                string       name = Request.Form.username;
                string       pass = Request.Form.password;
                UserIdentity user;

                if (userMapper.FindUser(name, pass, out user))
                {
                    return(this.LoginAndRedirect(user.Guid, DateTime.Now.AddYears(1)));
                }

                ViewBag.Error = TextResources.InvalidLoginError;
                return(View["login.cshtml"]);
            };
            Get["/logout"] = parameter => this.Logout("/");

            Get["/add-location", true] = GetAddLocation;

            Post["/add-location", true] = PostAddLocation;

            Get["/add-has-location", true] = GetAddHasLocation;

            Post["/add-has-location", true] = async(parameters, ct) =>
            {
                this.RequiresAuthentication();

                var locationId         = int.Parse((string)FormHelpers.GetString(Request.Form, "location"));
                var personLocationPair = new PersonLocationPair(CurrentUserGuid(), locationId);
                await DataConnection.Ask(d => d.InsertHasLocationPairAsync(personLocationPair));

                return(await GetAddHasLocation(parameters, ct));
            };

            Get["/add-person", true] = GetAddPerson;

            Post["/add-person", true] = PostAddPerson;

            Get["/newsfeed", true] = GetNewsfeed;

            Get["/dashboard", true] = GetDashboard;

            Post["/dashboard", true] = PostDashboard;

            Get["/compare-graph", true] = CompareGraph;

            Get["/set-culture"] = parameters =>
            {
                string lcid = Request.Query["lcid"];
                Request.Session["CurrentCulture"] = CultureInfo.GetCultureInfo(lcid);
                var referrer = Request.Headers.Referrer;
                return(Response.AsRedirect(string.IsNullOrWhiteSpace(referrer) ? "/" : referrer));
            };

            Get["/view-graph/{sensorId}/{startTime}/{endTime}/{maxMeasurements}"] = parameters =>
            {
                // sensor ids, start times, end times and max number of measurements are formatted
                // as comma-separated lists.

                var sensorIds       = ((string)parameters["sensorId"]).Split(',').Select(s => int.Parse(s.Trim())).ToArray();
                var startTimes      = ((string)parameters["startTime"]).Split(',').Select(s => DateTime.Parse(s.Trim())).ToArray();
                var endTimes        = ((string)parameters["endTime"]).Split(',').Select(s => DateTime.Parse(s.Trim())).ToArray();
                var maxMeasurements = ((string)parameters["maxMeasurements"]).Split(',').Select(s => int.Parse(s.Trim())).ToArray();

                if (sensorIds.Length != startTimes.Length ||
                    sensorIds.Length != endTimes.Length ||
                    sensorIds.Length != maxMeasurements.Length)
                {
                    return(HttpStatusCode.BadRequest);
                }

                var model = new List <AutofitRange>();
                for (int i = 0; i < sensorIds.Length; i++)
                {
                    model.Add(new AutofitRange(sensorIds[i], startTimes[i], endTimes[i], maxMeasurements[i]));
                }
                return(View["view-graph.cshtml", model]);
            };


            Get["/cluster", true] = getCluster;
        }
        private async Task <object> PostAddPerson(dynamic parameters, CancellationToken ct)
        {
            ViewBag.Success = "";
            ViewBag.Error   = "";

            string   username       = FormHelpers.GetString(Request.Form, "personusername");
            string   name           = FormHelpers.GetString(Request.Form, "personname");
            string   password       = FormHelpers.GetRawString(Request.Form, "personpassword");
            string   repeatPassword = FormHelpers.GetRawString(Request.Form, "personpasswordrepeat");
            string   address        = FormHelpers.GetString(Request.Form, "personaddress");
            DateTime?birthdate      = FormHelpers.GetDate(Request.Form, "personbirthdate");
            string   city           = FormHelpers.GetString(Request.Form, "personcity");
            string   zipcode        = FormHelpers.GetString(Request.Form, "personzipcode");

            if (string.IsNullOrWhiteSpace(username))
            {
                ViewBag.Error = TextResources.EmptyUserNameError;
            }
            else if (string.IsNullOrWhiteSpace(name))
            {
                ViewBag.Error = TextResources.EmptyNameError;
            }
            else if (string.IsNullOrWhiteSpace(password))
            {
                ViewBag.Error = TextResources.EmptyPasswordError;
            }
            else if (password != repeatPassword)
            {
                ViewBag.Error = TextResources.PasswordMismatchError;
            }
            else if (!birthdate.HasValue)
            {
                ViewBag.Error = TextResources.BadlyFormattedBirthDateError;
            }
            else
            {
                // DataConnection.Ask is used here, because it conveniently wraps everything in
                // a single transaction.
                await DataConnection.Ask(async dc =>
                {
                    var sender = await dc.GetPersonByUsernameAsync(username);
                    if (sender != null)
                    {
                        ViewBag.Error = string.Format(TextResources.PersonAlreadyExistsError, username);
                    }
                    else
                    {
                        var personData = new PersonData(username, password, name, birthdate.Value, address, city, zipcode, false);
                        // Create the person
                        await dc.InsertPersonAsync(personData);
                        ViewBag.Success = TextResources.AddedPersonMessage;
                    }
                });
            }

            if (string.IsNullOrWhiteSpace((string)ViewBag.Error))
            {
                UserIdentity user;
                UserMapper.FindUser(username, password, out user);
                // Everything went fine. Log in and redirect to the profile page.
                return(this.LoginAndRedirect(user.Guid, DateTime.Now.AddYears(1), "/person/" + username));
            }
            else
            {
                return(await GetAddPerson(parameters, ct));
            }
        }
        private async Task <dynamic> GetMessage(dynamic parameters, CancellationToken ct)
        {
            var messages = await DataConnection.Ask(x => x.GetMessagesAsync());

            return(View["message.cshtml", messages]);
        }
示例#20
0
        public IUserIdentity GetUserFromIdentifier(Guid guid, NancyContext context)
        {
            var person = DataConnection.Ask(dc => dc.GetPersonByGuidAsync(guid)).Result;

            return(person == null ? null : new UserIdentity(person));
        }