Skip to content

Commit bc376b0

Browse files
committed
Added Wargames App
1 parent a2ea85c commit bc376b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+6682
-0
lines changed

wargames/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div align="center">
2+
<img src="assets/banner.jpg" />
3+
</div>
4+
5+
We are building framework at https://github.com/Walchand-Linux-Users-Group/wargames

wargames/backend/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Backend
2+
3+
## Core
4+
* Includes exact code that works when someone SSH into Wargame.
5+
6+
## API
7+
* API for analytics, scoreboard and user verification.

wargames/backend/api/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
.env

wargames/backend/api/db.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"sync"
6+
7+
"go.mongodb.org/mongo-driver/mongo"
8+
"go.mongodb.org/mongo-driver/mongo/options"
9+
)
10+
11+
/* Used to create a singleton object of MongoDB client.
12+
Initialized and exposed through GetMongoClient().*/
13+
var clientInstance *mongo.Client
14+
15+
//Used during creation of singleton client object in GetMongoClient().
16+
var clientInstanceError error
17+
18+
//Used to execute client creation procedure only once.
19+
var mongoOnce sync.Once
20+
21+
//GetMongoClient - Return mongodb connection to work with
22+
func GetMongoClient(MONGO_URI string) (*mongo.Client, error) {
23+
//Perform connection creation operation only once.
24+
mongoOnce.Do(func() {
25+
// Set client options
26+
clientOptions := options.Client().ApplyURI(MONGO_URI)
27+
// Connect to MongoDB
28+
client, err := mongo.Connect(context.TODO(), clientOptions)
29+
if err != nil {
30+
clientInstanceError = err
31+
}
32+
// Check the connection
33+
err = client.Ping(context.TODO(), nil)
34+
if err != nil {
35+
clientInstanceError = err
36+
}
37+
clientInstance = client
38+
})
39+
return clientInstance, clientInstanceError
40+
}

wargames/backend/api/endpoints.go

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
"io/ioutil"
8+
"log"
9+
"math/rand"
10+
"net/http"
11+
"regexp"
12+
"time"
13+
14+
"github.com/gorilla/mux"
15+
"go.mongodb.org/mongo-driver/bson"
16+
"go.mongodb.org/mongo-driver/mongo/options"
17+
)
18+
19+
func initAPI() {
20+
21+
router := mux.NewRouter().StrictSlash(true)
22+
23+
router.HandleFunc("/", alive)
24+
router.HandleFunc("/auth", auth)
25+
router.HandleFunc("/register", register)
26+
router.HandleFunc("/leaderboard", leaderboard)
27+
router.HandleFunc("/status", status)
28+
29+
log.Fatal(http.ListenAndServe(":"+getEnv("PORT"), router))
30+
}
31+
32+
var pool = "abcdefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
33+
34+
func randomString(l int) string {
35+
rand.Seed(time.Now().UnixNano())
36+
37+
bytes := make([]byte, l)
38+
39+
for i := 0; i < l; i++ {
40+
bytes[i] = pool[rand.Intn(len(pool))]
41+
}
42+
43+
return string(bytes)
44+
}
45+
46+
func makeTimestamp() int64 {
47+
return time.Now().UnixNano() / int64(time.Millisecond)
48+
}
49+
50+
func alive(w http.ResponseWriter, r *http.Request) {
51+
fmt.Fprintf(w, "I am alive!")
52+
}
53+
54+
func register(w http.ResponseWriter, r *http.Request) {
55+
56+
if r.Method != http.MethodPost {
57+
w.WriteHeader(http.StatusBadRequest)
58+
return
59+
}
60+
61+
reqBody, _ := ioutil.ReadAll(r.Body)
62+
63+
type body struct {
64+
Username string `json:"username"`
65+
Password string `json:"password"`
66+
Name string `json:"name"`
67+
ApiToken string `json:"apiToken"`
68+
}
69+
70+
user := body{}
71+
72+
err := json.Unmarshal(reqBody, &user)
73+
74+
if err != nil {
75+
w.WriteHeader(http.StatusBadRequest)
76+
return
77+
}
78+
79+
if user.ApiToken != getEnv("API_TOKEN") {
80+
w.WriteHeader(http.StatusBadRequest)
81+
return
82+
}
83+
84+
match, err := regexp.MatchString("[A-Za-z0-9]", user.Username)
85+
86+
if !match || len(user.Username) > 10 || err != nil {
87+
w.WriteHeader(http.StatusBadRequest)
88+
return
89+
}
90+
91+
passMatch, err := regexp.MatchString("[a-zA-Z0-9]", user.Password)
92+
93+
if !passMatch || err != nil {
94+
w.WriteHeader(http.StatusBadRequest)
95+
return
96+
}
97+
98+
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
99+
100+
users_collection := clientInstance.Database("wargames").Collection("users")
101+
102+
var dublicate body
103+
users_collection.FindOne(ctx, bson.M{
104+
"username": user.Username,
105+
}).Decode(&dublicate)
106+
107+
if (dublicate != body{}) {
108+
w.WriteHeader(http.StatusBadRequest)
109+
return
110+
}
111+
112+
_, err = users_collection.InsertOne(ctx, bson.M{
113+
"username": user.Username,
114+
"password": user.Password,
115+
"name": user.Name,
116+
"level": 0,
117+
"timestamp": makeTimestamp(),
118+
"nextPassword": "WLUG{" + randomString(8) + "}",
119+
})
120+
121+
if err != nil {
122+
w.WriteHeader(http.StatusInternalServerError)
123+
return
124+
}
125+
126+
type Payload struct {
127+
Status string
128+
}
129+
130+
var p Payload
131+
p.Status = "Success"
132+
133+
w.Header().Set("Content-Type", "application/json")
134+
json.NewEncoder(w).Encode(p)
135+
}
136+
137+
func auth(w http.ResponseWriter, r *http.Request) {
138+
if r.Method != http.MethodPost {
139+
w.WriteHeader(http.StatusBadRequest)
140+
return
141+
}
142+
143+
reqBody, _ := ioutil.ReadAll(r.Body)
144+
145+
type body struct {
146+
Username string `json:"username"`
147+
Password string `json:"password"`
148+
ApiToken string `json:"apiToken"`
149+
}
150+
151+
user := body{}
152+
153+
err := json.Unmarshal(reqBody, &user)
154+
155+
if err != nil {
156+
w.WriteHeader(http.StatusBadRequest)
157+
return
158+
}
159+
160+
fmt.Println(user)
161+
162+
if user.ApiToken != getEnv("API_TOKEN") {
163+
w.WriteHeader(http.StatusBadRequest)
164+
return
165+
}
166+
167+
users_collection := clientInstance.Database("wargames").Collection("users")
168+
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
169+
170+
type User struct {
171+
Username string `json:"username"`
172+
Password string `json:"password"`
173+
Level int64 `json:"level"`
174+
Timestamp int64 `json:"timestamp"`
175+
NextPassword string `json:"nextPassword"`
176+
}
177+
178+
var dublicate User
179+
users_collection.FindOne(ctx, bson.M{
180+
"username": user.Username,
181+
}).Decode(&dublicate)
182+
183+
type Payload struct {
184+
Username string `json:"username"`
185+
Won bool `json:"won"`
186+
Level int64 `json:"level"`
187+
Status string `json:"status"`
188+
NextPassword string `json:"nextPassword"`
189+
}
190+
191+
var p Payload
192+
193+
p.Username = user.Username
194+
195+
if user.Password == dublicate.Password {
196+
p.Level = dublicate.Level
197+
p.Won = false
198+
p.Status = "success"
199+
p.NextPassword = dublicate.NextPassword
200+
w.Header().Set("Content-Type", "application/json")
201+
json.NewEncoder(w).Encode(p)
202+
return
203+
} else if user.Password == dublicate.NextPassword {
204+
205+
_, err := users_collection.UpdateOne(ctx, bson.M{"username": user.Username}, bson.M{
206+
"$set": bson.M{
207+
"level": dublicate.Level + 1,
208+
"password": dublicate.NextPassword,
209+
"timestamp": makeTimestamp(),
210+
"nextPassword": "WLUG{" + randomString(8) + "}",
211+
},
212+
})
213+
214+
if err != nil {
215+
w.WriteHeader(http.StatusInternalServerError)
216+
return
217+
}
218+
219+
p.Level = dublicate.Level + 1
220+
p.Won = true
221+
p.Status = "success"
222+
p.NextPassword = dublicate.NextPassword
223+
w.Header().Set("Content-Type", "application/json")
224+
json.NewEncoder(w).Encode(p)
225+
return
226+
}
227+
228+
w.WriteHeader(http.StatusBadRequest)
229+
}
230+
231+
func status(w http.ResponseWriter, r *http.Request) {
232+
if r.Method != http.MethodPost {
233+
w.WriteHeader(http.StatusBadRequest)
234+
return
235+
}
236+
237+
reqBody, _ := ioutil.ReadAll(r.Body)
238+
239+
type body struct {
240+
Username string `json:"username"`
241+
ApiToken string `json:"apiToken"`
242+
}
243+
244+
user := body{}
245+
246+
err := json.Unmarshal(reqBody, &user)
247+
248+
if err != nil {
249+
w.WriteHeader(http.StatusBadRequest)
250+
return
251+
}
252+
253+
fmt.Println(user)
254+
255+
if user.ApiToken != getEnv("API_TOKEN") {
256+
w.WriteHeader(http.StatusBadRequest)
257+
return
258+
}
259+
260+
users_collection := clientInstance.Database("wargames").Collection("users")
261+
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
262+
263+
type User struct {
264+
Username string `json:"username"`
265+
Password string `json:"password"`
266+
Level int64 `json:"level"`
267+
Timestamp int64 `json:"timestamp"`
268+
NextPassword string `json:"nextPassword"`
269+
}
270+
271+
var dublicate User
272+
users_collection.FindOne(ctx, bson.M{
273+
"username": user.Username,
274+
}).Decode(&dublicate)
275+
276+
type Payload struct {
277+
Username string `json:"username"`
278+
Won bool `json:"won"`
279+
Level int64 `json:"level"`
280+
Status string `json:"status"`
281+
NextPassword string `json:"nextPassword"`
282+
}
283+
284+
var p Payload
285+
286+
p.Username = user.Username
287+
288+
p.Level = dublicate.Level
289+
p.Won = false
290+
p.Status = "success"
291+
p.NextPassword = dublicate.NextPassword
292+
w.Header().Set("Content-Type", "application/json")
293+
json.NewEncoder(w).Encode(p)
294+
295+
}
296+
297+
func leaderboard(w http.ResponseWriter, r *http.Request) {
298+
299+
if r.Method != http.MethodGet {
300+
w.WriteHeader(http.StatusBadRequest)
301+
return
302+
}
303+
304+
users_collection := clientInstance.Database("wargames").Collection("users")
305+
ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
306+
307+
findOptions := options.Find()
308+
309+
findOptions.SetSort(bson.D{{"level", -1}, {"timeStamp", 1}})
310+
311+
cursor, err := users_collection.Find(ctx, bson.D{}, findOptions)
312+
313+
if err != nil {
314+
w.WriteHeader(http.StatusInternalServerError)
315+
return
316+
}
317+
318+
type User struct {
319+
Username string `json:"username"`
320+
Name string `json:"name"`
321+
Level int64 `json:"level"`
322+
Rank int `json:"rank"`
323+
}
324+
325+
var results []User
326+
327+
if err = cursor.All(context.TODO(), &results); err != nil {
328+
panic(err)
329+
}
330+
331+
for i := range results {
332+
results[i].Rank = i + 1
333+
}
334+
335+
w.Header().Set("Content-Type", "application/json")
336+
json.NewEncoder(w).Encode(results)
337+
}

0 commit comments

Comments
 (0)