);
}
diff --git a/client/js/pages/Index.js b/client/js/pages/Index.js
index 51f19f4..3c21c8d 100644
--- a/client/js/pages/Index.js
+++ b/client/js/pages/Index.js
@@ -43,7 +43,7 @@ export default class Index extends React.Component {
- {typeof this.page === 'undefined' && !fetching ? : null}
+ {typeof this.page === 'undefined' && !fetching ? : null}
{this.page === 'post' && !fetching ? : null}
{fetching ? loadingElement : null}
diff --git a/client/js/redux/actions.js b/client/js/redux/actions.js
index 47adfdd..a191abd 100644
--- a/client/js/redux/actions.js
+++ b/client/js/redux/actions.js
@@ -2,6 +2,12 @@ import * as types from "./constants";
import marked from 'marked';
import 'whatwg-fetch';
+export function increasePostLimit(){
+ return {
+ type: types.INCREASE_POST_LIMIT
+ }
+}
+
function initPreview(posts) {
return {
type: types.INIT_PREVIEW,
diff --git a/client/js/redux/constants.js b/client/js/redux/constants.js
index d9cc693..6d21a68 100644
--- a/client/js/redux/constants.js
+++ b/client/js/redux/constants.js
@@ -2,4 +2,5 @@
export const INIT_PREVIEW = 'INIT_PREVIEW';
export const FILTER_PREVIEW = 'FILTER_PREVIEW';
export const LOAD_POST = 'LOAD_POST';
-export const FETCHING = 'FETCHING';
\ No newline at end of file
+export const FETCHING = 'FETCHING';
+export const INCREASE_POST_LIMIT = 'INCREASE_POST_LIMIT';
\ No newline at end of file
diff --git a/client/js/redux/reducers.js b/client/js/redux/reducers.js
index 37bfec8..ebf0d11 100644
--- a/client/js/redux/reducers.js
+++ b/client/js/redux/reducers.js
@@ -14,12 +14,10 @@ const defaultState = {
preview: {
posts: []
},
- filteredPreview: {
- posts: []
- },
post: "",
fetched: false,
- fetching: false
+ fetching: false,
+ postLimit: 10
};
//default reducer
@@ -32,10 +30,6 @@ function reducer(state = defaultState, action) {
fetched: true,
fetching: false
});
- case types.FILTER_PREVIEW:
- return Object.assign({}, state, {
- filteredPreview: Object.assign({}, state.filteredPreview, action.posts)
- });
case types.LOAD_POST:
return Object.assign({}, state, {
post: action.post,
@@ -47,6 +41,10 @@ function reducer(state = defaultState, action) {
fetched : false,
fetching: true
});
+ case types.INCREASE_POST_LIMIT:
+ return Object.assign({}, state, {
+ postLimit : state.postLimit + 10
+ });
}
//return present state if no actions get called
diff --git a/package.json b/package.json
index b0cfce2..e744041 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,9 @@
"build": "webpack && babel-node metadata.js",
"c9": "webpack-dev-server --port $PORT --host $IP --hot --content-base dist --history-api-fallback",
"dev": "webpack-dev-server --content-base public --inline --hot --history-api-fallback",
- "prod": "export NODE_ENV=production && webpack -p && babel-node metadata.js",
- "prod-win": "set NODE_ENV=production && webpack -p && babel-node metadata.js"
+ "prod": "export NODE_ENV=production && webpack -p && babel-node metadata.js && go build",
+ "prod-win": "set NODE_ENV=production && webpack -p && babel-node metadata.js && go build",
+ "deploy" : "npm run prod && ./mywebsite"
},
"repository": {
"type": "git",
diff --git a/server.go b/server.go
index 9377d20..6199475 100644
--- a/server.go
+++ b/server.go
@@ -4,7 +4,8 @@ import (
"log"
"net/http"
"strconv"
-
+ "github.com/NYTimes/gziphandler"
+
//local import paths relative to app.yaml file
"mywebsite/server/controller/api"
"mywebsite/server/db"
@@ -34,7 +35,10 @@ func main(){
api.Configure(configurations.Api)
db.Mongo.Connect()
-
+
+ //register middleware
+ handle := gziphandler.GzipHandler(route.Routes())
+
log.Println("Starting Server...")
- log.Println(http.ListenAndServe(":"+strconv.Itoa(configurations.Port), route.Routes()))
+ log.Println(http.ListenAndServe(":"+strconv.Itoa(configurations.Port), handle))
}
From 0c531a30c254a140fbed4ea4f7d359a7811fa6a5 Mon Sep 17 00:00:00 2001
From: mgerb42
Date: Wed, 31 Aug 2016 17:46:05 +0000
Subject: [PATCH 2/8] new post - updated server directories
---
package.json | 4 +-
.../Web Stuff/2016-08-30-ubuntu16-mongodb.md | 206 ++++++++++++++++++
server/controller/redirect.go | 2 +-
server/model/raw_sensor/raw_sensor.go | 53 +----
server.go => server/mywebsite.go | 16 --
server/utils/config.go | 2 +-
6 files changed, 213 insertions(+), 70 deletions(-)
create mode 100644 posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md
rename server.go => server/mywebsite.go (66%)
diff --git a/package.json b/package.json
index e744041..2221191 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,8 @@
"build": "webpack && babel-node metadata.js",
"c9": "webpack-dev-server --port $PORT --host $IP --hot --content-base dist --history-api-fallback",
"dev": "webpack-dev-server --content-base public --inline --hot --history-api-fallback",
- "prod": "export NODE_ENV=production && webpack -p && babel-node metadata.js && go build",
- "prod-win": "set NODE_ENV=production && webpack -p && babel-node metadata.js && go build",
+ "prod": "export NODE_ENV=production && webpack -p && babel-node metadata.js && go build ./server/mywebsite.go",
+ "prod-win": "set NODE_ENV=production && webpack -p && babel-node metadata.js && go build ./server/mywebsite.go",
"deploy" : "npm run prod && ./mywebsite"
},
"repository": {
diff --git a/posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md b/posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md
new file mode 100644
index 0000000..57b2997
--- /dev/null
+++ b/posts/Web Stuff/2016-08-30-ubuntu16-mongodb.md
@@ -0,0 +1,206 @@
+# Installing and setting up authentication with MongoDB on Ubuntu 16.04.1
+
+I recently spun up a new virtual machine on Digital Ocean and I decided to try the latest version
+of Ubuntu.. because why not? I wanted to just host a MongoDB instance because I was going to host my site on Google's App Engine.
+Turns out Google blocks any outgoing requests that are not HTTP.
+(This prevents the Go [MGO](https://godoc.org/gopkg.in/mgo.v2) driver from connecting)
+
+***
+
+## Installing MongoDB
+
+Luckily Digital Ocean offers great documentation when it comes to installing software. They usually have guides
+and tutorials that are fairly up to date. I first followed [this guide](https://www.digitalocean.com/community/tutorials/how-to-install-mongodb-on-ubuntu-16-04)
+to get MongoDB installed.
+
+On previous versions of Ubuntu, MongoDB was installed as a service. Newer versions use Systemd to run the database.
+Systemd uses different commands to check database statistics.
+
+The Systemd configuration is located in a few different places, but mine seems to work in the following directory.
+Here the run command can be edited, although this probably does not need to be done
+as most settings can be adjusted in the MongoDB config file.
+
+MongoDB systemd config
+```bash
+ /lib/systemd/system/mongod.service
+```
+
+MongoDB config
+```bash
+ /etc/mongod.conf
+```
+
+Service as well as systemd can be used to start and stop MongoDB.
+These commands will do the same thing, which is nice.
+```bash
+ sudo service mongod
+ sudo systemctl mongod
+```
+
+Although you can start, stop, and restart MongoDB with service and systemctl,
+MongoDB does not show up when listing all services.
+```bash
+ sudo service --status-all
+```
+
+Systemclt must now be used
+```bash
+ sudo systemctl status
+```
+
+## Enabling security for external connections
+
+Any time a port is opened up for a MongoDB instance security precautions must be taken.
+[There are thousands of MongoDB instances that are exposed to the internet.](http://www.securityweek.com/thousands-mongodb-databases-found-exposed-internet)
+There are a few reasons for this. MongoDB is usually run on the same machine of web applications,
+therefore the port it is running on should not be opened up at all. MongoDB can also be tricky to configure properly
+and a system admin must know exactly what they are doing in making the database secure. Login credentials do not
+even need to be set up if the port it is running on is not even open. As soon as that port is opened up,
+unwanted guests can gain easy access, especially if it is running on the default port (27018).
+
+The first thing to do when running MongoDB for external access is to run it on a completely different port.
+Why run it on the port where attackers know exactly what they are looking for?
+
+Security authentication must be enabled in the MongoDB config file. It is turned off by default.
+Make sure to do this after creating user accounts or else access will be denied.
+
+## Creating user accounts
+
+Although this probably isn't the most secure thing to do, I start out by creating a root admin.
+I do this because it allows me control over any database and it gives me easier access and power.
+My database doesn't store any sensative information so I am okay with this.
+
+A root admin can be created by connecting to the server with the command `mongo` using the admin database.
+```bash
+ mongo
+ use admin
+```
+
+Databases can also be listed
+```bash
+ show dbs
+```
+
+Use the admin database and create a root user
+```bash
+ db.createUser(
+ {
+ user: "admin",
+ pwd: "password",
+ roles: ["root"]
+ }
+ )
+```
+
+Verify that the user was created
+```bash
+ db.getUsers()
+```
+
+Lets go enable security
+```bash
+ sudo nano /etc/mongod.conf
+```
+
+Uncomment `#security` by removing the `#` and add this line after
+```bash
+ security:
+ authorization: enabled
+```
+
+Restart database or reboot the system
+```bash
+ sudo systemctl restart mongod
+```
+
+We can now authenticate to the database as our newly created root admin
+```bash
+ mongo admin --port 27017 -u 'admin' -p 'password'
+```
+
+## Difficulties configuring users
+
+When I first started setting up users I had a heck of a time. I wasn't sure which database to use for certain
+users or what permissions I had to give them. Part of this is due to my impatience of not reading the
+documentation thoroughly.
+
+Server wide users/admins MUST be in the admin database. We created a root use in the admin database
+previously so that user should have access to any database in the server. All database users must be in
+their respective database. For example if we want to use the "test" database, users must be created
+within this database in order to gain access. Although access can be gained with a root admin account,
+this is something that should not be done in production.
+
+Lets create a read/write user for the "test" database
+```bash
+ use test
+
+ db.createUser(
+ {
+ user: "user",
+ pwd: "password",
+ roles: ["readWrite"]
+ }
+ )
+```
+
+Verify that the user was created
+```bash
+ db.getUsers()
+```
+
+Login as this user
+```bash
+ mongo test --port 27017 -u 'user' -p 'admin'
+```
+
+Now a proper user should be set up for read/write access. This is the exact method I used to
+gain access to an external database the Go's MGO MongoDB database driver.
+
+### Scripts for easier access to the database
+
+I created some shell scripts on my database server with credentials saved because I use long random passwords
+that I cannot remember off the top of my head. (keep in mind this increases security risks)
+It took me awhile to get this to work because some syntax did not work for me when inside of a shell script.
+
+I created a file called `mongo_admin.sh` and one called `mongo_user.sh`.
+
+The files look like this
+```bash
+ mongo admin --port 27017 -u 'user' -p 'password'
+```
+
+This was frustrating because I figured out it would not work when using double quotes
+inside of the shell script, although double quotes work when issuing the command manually.
+I also realized that a database must be specified in order to connect. This can be done
+like above, or like this.
+```bash
+ mongo --port 27017 -u 'user' -p 'password' --authenticationDatabase admin
+```
+
+## Firewall
+
+Firewall rules must be changed to enable external database access. First of all, edit the MongoDB config
+file and change the default database port. Once that is changed use [UFW](https://help.ubuntu.com/community/UFW)
+to change firewall rules. For this example I will change MongoDB to run on port 27018.
+
+```bash
+ ufw enable
+ ufw status
+ ufw allow 27018/tcp
+```
+
+This will allow all incoming connections to the database. It is advised to only allow
+incoming connections from the web application server that is being used.
+
+Allow to certain ip
+```bash
+ ufw allow from to any port 27018
+```
+
+## Conclusion
+
+MongoDB can be tricky to set up, but it is highly recommened to go through the entire process.
+In the end I decided not to host my MongoDB instance externally so I did not go through
+the entire [MongoDB security check list](https://docs.mongodb.com/v2.6/administration/security-checklist/#audit-system-activity).
+There are a few other things to do such as adding encryption and monitoring system activity, but
+I covered most of the important issues.
\ No newline at end of file
diff --git a/server/controller/redirect.go b/server/controller/redirect.go
index 0b78f0f..35299bd 100644
--- a/server/controller/redirect.go
+++ b/server/controller/redirect.go
@@ -11,7 +11,7 @@ func DiscordRedirect(w http.ResponseWriter, r *http.Request, _ httprouter.Params
http.Redirect(w, r, "https://discordapp.com/invite/0Z2tzxKECEj2BHwj", 301)
}
-// Redirect to discord
+// Redirect to vpn
func VPNRedirect(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
http.Redirect(w, r, "https://mitchel.io:943", 301)
}
diff --git a/server/model/raw_sensor/raw_sensor.go b/server/model/raw_sensor/raw_sensor.go
index c329a09..9b91b54 100644
--- a/server/model/raw_sensor/raw_sensor.go
+++ b/server/model/raw_sensor/raw_sensor.go
@@ -34,6 +34,7 @@ func (s *Data) toJson() string {
}
+//default store structure
func (s *Data) StoreData() error {
if db.Mongo.Connected() {
@@ -57,13 +58,13 @@ func (s *Data) StoreData() error {
}
//handle queries for all sensors page
-//********************************************************************************
type DataStore_AllSensors struct {
ID string `json:"location" bson:"_id"`
Temperature float64 `json:"temperature" bson:"temperature"`
Updated time.Time `json:"updated" bson:"updated"`
}
+//get latest update from each unique sensor
func GetAllSensors() ([]DataStore_AllSensors, error) {
s := []DataStore_AllSensors{}
@@ -88,52 +89,4 @@ func GetAllSensors() ([]DataStore_AllSensors, error) {
} else {
return s, errors.New("Query failed")
}
-}
-
-//********************************************************************************
-
-//get sensor information by location
-//********************************************************************************
-type DataStore_SensorByLocation struct {
- Id sensorByLocation `json:"_id" bson:"_id"`
-}
-
-type sensorByLocation struct {
- Year int `json:"year" bson:"year"`
- Month int `json:"month" bson:"month"`
- Location string `json:"location" bson:"location"`
-}
-
-/*
-func GetSensorInfoByLocation(sensor_location string) ([]DataStore_SensorByLocation, error) {
- s := []DataStore_SensorByLocation{}
- if db.Mongo.Connected() == true {
- session := db.Mongo.Session.Copy()
- defer session.Close()
- c := session.DB(db.Mongo.Info.Database).C(collection)
- err := c.Pipe([]bson.M{{"$project": bson.M{"location": "$location", "year": bson.M{"$year": "$updated"}, "month": bson.M{"$month": "$updated"}}},
- bson.M{"$match": bson.M{"location": sensor_location}},
- bson.M{"$group": bson.M{"_id": bson.M{"year": "$year", "month": "$month", "location": "$location"}}},
- bson.M{"$sort": bson.M{"_id.year": -1, "_id.month": -1}}}).All(&s)
- if err != nil {
- log.Println(err)
- return s, nil
- }
- return s, nil
- } else {
- return s, errors.New("Query failed")
- }
-}
-*/
-
-//********************************************************************************
-
-/*************************
-testStore := model.SensorData{
- ID: bson.NewObjectId(),
- Temperature: 34.2,
- Humidity: 33.22,
- Location: "Grand Meadow",
- Updated: time.Now(),
-}
-**************************/
+}
\ No newline at end of file
diff --git a/server.go b/server/mywebsite.go
similarity index 66%
rename from server.go
rename to server/mywebsite.go
index 6199475..edb23b2 100644
--- a/server.go
+++ b/server/mywebsite.go
@@ -6,28 +6,12 @@ import (
"strconv"
"github.com/NYTimes/gziphandler"
- //local import paths relative to app.yaml file
"mywebsite/server/controller/api"
"mywebsite/server/db"
"mywebsite/server/route"
"mywebsite/server/utils"
)
-/* for app engine
-func init() {
- configurations := utils.ReadConfig()
-
- db.Configure(configurations.Database)
- api.Configure(configurations.Api)
-
- db.Mongo.Connect()
-
- router := route.Routes()
-
- http.Handle("/", router)
-}
-*/
-
func main(){
configurations := utils.ReadConfig()
diff --git a/server/utils/config.go b/server/utils/config.go
index 4b60f40..e6b45b8 100644
--- a/server/utils/config.go
+++ b/server/utils/config.go
@@ -14,7 +14,7 @@ import (
type Config struct {
Database db.DatabaseInfo `json:"database"`
Api api.ApiInfo `json:"api"`
- Port int `json:"port"`
+ Port int `json:"port"`
}
//read the config file and return JsonObject struct
From f8ccec7ae0b7abcb6ad0bc7e03fe6e06257c6ef0 Mon Sep 17 00:00:00 2001
From: mgerb42
Date: Thu, 1 Sep 2016 04:25:58 +0000
Subject: [PATCH 3/8] finished paging
---
client/assets/scss/Content.scss | 3 +++
client/assets/scss/main.scss | 13 +++++++++++++
client/js/components/Preview.js | 9 +++++----
client/js/components/sensors/SensorList.js | 1 -
client/js/pages/Index.js | 6 +++++-
package.json | 6 ++++--
readme.md | 13 +++++--------
server/utils/config.go | 2 --
8 files changed, 35 insertions(+), 18 deletions(-)
diff --git a/client/assets/scss/Content.scss b/client/assets/scss/Content.scss
index 55c9552..fdd6a11 100644
--- a/client/assets/scss/Content.scss
+++ b/client/assets/scss/Content.scss
@@ -29,4 +29,7 @@
pre {
white-space: pre-wrap;
}
+ .btn{
+ width: 100%;
+ }
}
diff --git a/client/assets/scss/main.scss b/client/assets/scss/main.scss
index 9e9b508..0c58bf9 100644
--- a/client/assets/scss/main.scss
+++ b/client/assets/scss/main.scss
@@ -1,6 +1,7 @@
@import './utils.scss';
$linkColor: #3598db;
+$backgroundColor: #FFFFFF;
html {
font-family: 'Roboto Slab', serif;
@@ -9,6 +10,7 @@ html {
overflow-y: scroll;
}
body {
+ background-color: $backgroundColor;
max-width: 100%;
overflow-x: hidden;
position: relative;
@@ -79,3 +81,14 @@ hr {
flex: 1;
justify-content: center;
}
+.btn{
+ background-color: $backgroundColor;
+ border: 1px solid #DADADA;
+ border-radius: .2em;
+ cursor: pointer;
+ padding: .5em;
+
+ &:hover{
+ background-color: #F3F3F3;
+ }
+}
\ No newline at end of file
diff --git a/client/js/components/Preview.js b/client/js/components/Preview.js
index db6f688..8c38a30 100644
--- a/client/js/components/Preview.js
+++ b/client/js/components/Preview.js
@@ -7,7 +7,7 @@ export default class Preview extends React.Component{
insertPosts(posts){
let elements = [];
- for (let i in posts){
+ for (let i = 0; i < this.props.postLimit && i < posts.length; i++){
elements.push(
@@ -22,8 +22,6 @@ export default class Preview extends React.Component{