diff --git a/Dockerfile b/Dockerfile
index d6499ec1027ec8e3eaf63f279282628690d6f984..e3da96a638a495e9ea8c0b9f25845017e8955bbe 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -4,5 +4,5 @@ COPY package*.json ./
 RUN npm install
 RUN npm ci --only=production
 COPY . .
-EXPOSE 3000
+EXPOSE 5000
 CMD [ "npm", "start", "--force" ]
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c5b6dd6fc2c14b21ac27abfe4050131117f962d9..05c4c11f6797b7d67226fa03b30c6327b6fe9c69 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -448,6 +448,41 @@
         "uuid": "3.3.2"
       }
     },
+    "@nestjs/jwt": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-6.1.1.tgz",
+      "integrity": "sha512-XZEYC+p69N+Accktjho0B98TkwAKCZNt91+t08eukw7Gwk6FvfJB+aBzHCmQEaWUiAOpAo4eObgac86P12XOkw==",
+      "requires": {
+        "@types/jsonwebtoken": "7.2.8",
+        "jsonwebtoken": "8.4.0"
+      },
+      "dependencies": {
+        "@types/jsonwebtoken": {
+          "version": "7.2.8",
+          "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-7.2.8.tgz",
+          "integrity": "sha512-XENN3YzEB8D6TiUww0O8SRznzy1v+77lH7UmuN54xq/IHIsyWjWOzZuFFTtoiRuaE782uAoRwBe/wwow+vQXZw==",
+          "requires": {
+            "@types/node": "*"
+          }
+        },
+        "jsonwebtoken": {
+          "version": "8.4.0",
+          "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz",
+          "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==",
+          "requires": {
+            "jws": "^3.1.5",
+            "lodash.includes": "^4.3.0",
+            "lodash.isboolean": "^3.0.3",
+            "lodash.isinteger": "^4.0.4",
+            "lodash.isnumber": "^3.0.3",
+            "lodash.isplainobject": "^4.0.6",
+            "lodash.isstring": "^4.0.1",
+            "lodash.once": "^4.0.0",
+            "ms": "^2.1.1"
+          }
+        }
+      }
+    },
     "@nestjs/platform-express": {
       "version": "6.2.4",
       "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-6.2.4.tgz",
@@ -5879,6 +5914,20 @@
       "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
       "dev": true
     },
+    "passport-jwt": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/passport-jwt/-/passport-jwt-4.0.0.tgz",
+      "integrity": "sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==",
+      "requires": {
+        "jsonwebtoken": "^8.2.0",
+        "passport-strategy": "^1.0.0"
+      }
+    },
+    "passport-strategy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
+      "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
+    },
     "path-dirname": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
diff --git a/package.json b/package.json
index cecd109950851c302849f33d7e0487f56736a661..eaf64ea6d6af75e1ef9ecb38237a0f2326895fc2 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
   "dependencies": {
     "@nestjs/common": "^6.0.0",
     "@nestjs/core": "^6.0.0",
+    "@nestjs/jwt": "^6.1.1",
     "@nestjs/platform-express": "^6.0.0",
     "@nestjs/platform-socket.io": "^6.3.1",
     "@nestjs/typeorm": "^6.1.1",
@@ -31,6 +32,7 @@
     "class-validator": "^0.9.1",
     "express-rate-limit": "^4.0.4",
     "jsonwebtoken": "^8.5.1",
+    "passport-jwt": "^4.0.0",
     "pg": "^7.11.0",
     "pg-hstore": "^2.3.2",
     "reflect-metadata": "^0.1.12",
diff --git a/src/app.module.ts b/src/app.module.ts
index f591eb0f2c4e6b6de14f8f1d3de17aa73bcf4dff..f593d727a4ed2ba97cc5f7735b104380de65c162 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -1,15 +1,17 @@
 import { Module } from '@nestjs/common';
-import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
+import { APP_FILTER, APP_INTERCEPTOR, APP_GUARD } from '@nestjs/core';
 import { TypeOrmModule } from '@nestjs/typeorm';
 import { AppController } from './app.controller';
 import { AppService } from './app.service';
 import { Connection } from 'typeorm';
 import { UserModule } from './user/user.module';
+
 import { HttpErrorFilter } from './shared/http-error.filter';
 import { LoggingInterceptor } from './shared/logging.interceptor';
 import { MapMarkerModule } from './mapmarkers/mapmarkers.module';
 import { NotificationModule } from './notifications/notifications.module';
 import { GameModule } from './game/game.module';
+import { RolesGuard } from './shared/roles.guard';
 
 @Module({
   imports: [
@@ -30,6 +32,10 @@ import { GameModule } from './game/game.module';
       provide: APP_INTERCEPTOR,
       useClass: LoggingInterceptor,
     },
+    {
+      provide: APP_GUARD,
+      useClass: RolesGuard
+    }
   ],
 })
 export class AppModule {
diff --git a/src/game/coordinate.entity.ts b/src/game/coordinate.entity.ts
index 9c5a38c2e91924e8a20e73c1802510069c8e43ed..65ad6545eb030813a796cb4fef836030bf247154 100644
--- a/src/game/coordinate.entity.ts
+++ b/src/game/coordinate.entity.ts
@@ -1,84 +1,30 @@
 import {
-  Entity,
-  Column,
-  PrimaryGeneratedColumn,
-  OneToMany,
-  ManyToOne,
-  PrimaryColumn,
-} from 'typeorm';
-import {
-  Game_PersonEntity,
-  ObjectivePointEntity,
-  GameEntity,
-} from './game.entity';
-import { FactionEntity } from './faction.entity';
-
-@Entity('Coordinate')
-export class CoordinateEntity {
-  @PrimaryColumn('uuid') id: string;
-
-  @OneToMany(
-    type => MapDrawingEntity,
-    mapDrawings => mapDrawings.mapDrawings_coordinates,
-  )
-  mapDrawings: MapDrawingEntity[];
-  @OneToMany(
-    type => Game_PersonEntity,
-    game_persons => game_persons.game_person_coordinates,
-  )
-  game_persons: Game_PersonEntity[];
-  @OneToMany(
-    type => ObjectivePointEntity,
-    objective_points => objective_points.coordinate,
-  )
-  objective_points: ObjectivePointEntity[];
-  @OneToMany(type => MapEntity, maps => maps.coordinate)
-  maps: ObjectivePointEntity[];
-}
-
-@Entity('Map')
-export class MapEntity {
-  @PrimaryGeneratedColumn('uuid') mapId: string;
-
-  @ManyToOne(type => CoordinateEntity, coordinate => coordinate.maps)
-  coordinate: CoordinateEntity;
-  @OneToMany(type => GameEntity, games => games.map)
-  games: GameEntity[];
-  @OneToMany(type => MapDrawingEntity, mapDrawings => mapDrawings.map)
-  mapDrawings: MapDrawingEntity[];
-}
-
-@Entity('MapDrawing')
-export class MapDrawingEntity {
-  @PrimaryGeneratedColumn('uuid') mapDrawingId: string;
-  @Column({ type: 'bool' }) drawingIsActive: boolean;
-  @Column({ type: 'time' }) drawingValidTill: string;
-
-  @ManyToOne(
-    type => CoordinateEntity,
-    mapDrawings_coordinates => mapDrawings_coordinates.mapDrawings,
-  )
-  mapDrawings_coordinates: CoordinateEntity;
-  @ManyToOne(type => MapEntity, map => map.mapDrawings)
-  map: MapEntity;
-  @ManyToOne(
-    type => MapDrawingTypeEntity,
-    mapDrawingType => mapDrawingType.mapDrawings,
-  )
-  mapDrawingType: MapEntity;
-  @ManyToOne(type => FactionEntity, faction => faction.mapDrawings)
-  faction: FactionEntity;
-}
-
-@Entity('MapDrawingType')
-export class MapDrawingTypeEntity {
-  @PrimaryGeneratedColumn('uuid') mapDrawingTypeId: string;
-  @Column({ type: 'text' }) drawingTypeName: string;
-  @Column({ type: 'text' }) drawingTypeDescription: string;
-
-  @OneToMany(
-    type => MapDrawingEntity,
-    mapDrawings => mapDrawings.mapDrawingType,
-  )
-  mapDrawings: MapDrawingEntity[];
-}
+    Entity,
+    Column,
+    PrimaryGeneratedColumn,
+    OneToMany,
+    ManyToOne,
+    PrimaryColumn,
+    Timestamp,
+  } from 'typeorm';
+  import {
+    Game_PersonEntity,
+    ObjectivePointEntity,
+    GameEntity,
+  } from './game.entity';
+  import { FactionEntity } from './faction.entity';
+  
+  @Entity('MapDrawing')
+  export class MapDrawingEntity {
+    @PrimaryGeneratedColumn('uuid') mapDrawingId: string;
+    @Column({ type: 'bool' }) drawingIsActive: boolean;
+    @Column({ type: 'time' }) drawingValidTill: string;
+  
+    @Column({ type: 'json', nullable: true }) data: JSON;
+  
+    @ManyToOne(type => FactionEntity, faction => faction.mapDrawings)
+    faction: FactionEntity;
+    @ManyToOne(type => GameEntity, gameEntity => gameEntity.id)
+    gameId: GameEntity;
+  }
+  
\ No newline at end of file
diff --git a/src/game/faction.entity.ts b/src/game/faction.entity.ts
index 7caa5a57a008ed2075def6262b927dcc8de8b679..891421d3a41315549a9e589ef87ce1f22a9abc84 100644
--- a/src/game/faction.entity.ts
+++ b/src/game/faction.entity.ts
@@ -1,95 +1,95 @@
 import {
-  Entity,
-  Column,
-  PrimaryGeneratedColumn,
-  OneToMany,
-  ManyToOne,
-  Timestamp,
-} from 'typeorm';
-import { PersonEntity } from '../user/user.entity';
-import { GameEntity } from './game.entity';
-import { Game_PersonEntity } from './game.entity';
-import { MapDrawingEntity } from './coordinate.entity';
-
-//Faction, PowerUp, Faction_powerUp, FP_History, Score, Task
-
-@Entity('Faction')
-export class FactionEntity {
-  @PrimaryGeneratedColumn('uuid') factionId: string;
-  @Column({ type: 'text', unique: true }) factionName: string;
-  @Column({ type: 'text' }) factionPassword: string;
-  @Column({ type: 'float' }) multiplier: number;
-
-  @OneToMany(type => MapDrawingEntity, mapDrawings => mapDrawings.faction)
-  mapDrawings: MapDrawingEntity[];
-  @OneToMany(type => ScoreEntity, scores => scores.faction)
-  scores: ScoreEntity[];
-  @OneToMany(type => PowerUpEntity, powerUps => powerUps.factions)
-  powerUps: Faction_PowerUpEntity[];
-  @OneToMany(type => TaskEntity, tasks => tasks.faction)
-  tasks: TaskEntity[];
-  @OneToMany(type => Game_PersonEntity, game_persons => game_persons.faction)
-  game_persons: Game_PersonEntity[];
-  @ManyToOne(type => GameEntity, game => game.factions)
-  game: GameEntity;
-}
-
-@Entity('PowerUp')
-export class PowerUpEntity {
-  @PrimaryGeneratedColumn('uuid') powerUpId: string;
-  @Column({ type: 'text' }) powerUpName: string;
-  @Column({ type: 'text' }) powerUpDescription: string;
-  @Column({ type: 'int' }) amount: number;
-  @Column({ type: 'time' }) cooldown: string;
-
-  @OneToMany(type => FactionEntity, factions => factions.powerUps)
-  factions: Faction_PowerUpEntity[];
-}
-
-@Entity('Faction_PowerUp')
-export class Faction_PowerUpEntity {
-  @PrimaryGeneratedColumn('uuid') faction_powerUpId: string;
-
-  @ManyToOne(type => FactionEntity, faction => faction.powerUps)
-  faction: FactionEntity;
-  @ManyToOne(type => PowerUpEntity, powerUp => powerUp.factions)
-  powerUp: PowerUpEntity;
-  @OneToMany(type => FP_HistoryEntity, histories => histories.faction_PowerUp)
-  histories: FP_HistoryEntity[];
-}
-
-@Entity('FP_History')
-export class FP_HistoryEntity {
-  @PrimaryGeneratedColumn('uuid') historyId: string;
-  @Column({ type: 'timestamp' }) historyTimeStamp: Timestamp;
-
-  @ManyToOne(
-    type => Faction_PowerUpEntity,
-    faction_PowerUp => faction_PowerUp.histories,
-  )
-  faction_PowerUp: Faction_PowerUpEntity;
-}
-
-@Entity('Score')
-export class ScoreEntity {
-  @PrimaryGeneratedColumn('uuid') scoreId: string;
-  @Column({ type: 'float' }) score: number;
-  @Column({ type: 'timestamp' }) scoreTimeStamp: Timestamp;
-
-  @ManyToOne(type => FactionEntity, factionName => factionName.scores)
-  faction: FactionEntity;
-}
-
-@Entity('Task')
-export class TaskEntity {
-  @PrimaryGeneratedColumn('uuid') taskId: string;
-  @Column({ type: 'text' }) taskName: string;
-  @Column({ type: 'text' }) taskDescription: string;
-  @Column({ type: 'text' }) taskWinner: string;
-  @Column({ type: 'bool' }) taskIsActive: boolean;
-
-  @ManyToOne(type => FactionEntity, faction => faction.tasks)
-  faction: FactionEntity;
-  @ManyToOne(type => PersonEntity, person => person.tasks)
-  person: PersonEntity;
-}
+    Entity,
+    Column,
+    PrimaryGeneratedColumn,
+    OneToMany,
+    ManyToOne,
+    Timestamp,
+  } from 'typeorm';
+  import { GameEntity } from './game.entity';
+  import { Game_PersonEntity } from './game.entity';
+  import { MapDrawingEntity } from './coordinate.entity';
+  
+  //Faction, PowerUp, Faction_powerUp, FP_History, Score, Task
+  
+  @Entity('Faction')
+  export class FactionEntity {
+    @PrimaryGeneratedColumn('uuid') factionId: string;
+    @Column({ type: 'text', unique: true }) factionName: string;
+    @Column({ type: 'text' }) factionPassword: string;
+    @Column({ type: 'float' }) multiplier: number;
+  
+    @OneToMany(type => MapDrawingEntity, mapDrawings => mapDrawings.faction)
+    mapDrawings: MapDrawingEntity[];
+    @OneToMany(type => ScoreEntity, scores => scores.faction)
+    scores: ScoreEntity[];
+    @OneToMany(type => PowerUpEntity, powerUps => powerUps.factions)
+    powerUps: Faction_PowerUpEntity[];
+    @OneToMany(type => TaskEntity, tasks => tasks.faction)
+    tasks: TaskEntity[];
+    @OneToMany(type => Game_PersonEntity, game_persons => game_persons.faction)
+    game_persons: Game_PersonEntity[];
+    @ManyToOne(type => GameEntity, game => game.factions)
+    game: GameEntity;
+  }
+  
+  @Entity('PowerUp')
+  export class PowerUpEntity {
+    @PrimaryGeneratedColumn('uuid') powerUpId: string;
+    @Column({ type: 'text' }) powerUpName: string;
+    @Column({ type: 'text' }) powerUpDescription: string;
+    @Column({ type: 'int' }) amount: number;
+    @Column({ type: 'time' }) cooldown: string;
+  
+    @OneToMany(type => FactionEntity, factions => factions.powerUps)
+    factions: Faction_PowerUpEntity[];
+  }
+  
+  @Entity('Faction_PowerUp')
+  export class Faction_PowerUpEntity {
+    @PrimaryGeneratedColumn('uuid') faction_powerUpId: string;
+  
+    @ManyToOne(type => FactionEntity, faction => faction.powerUps)
+    faction: FactionEntity;
+    @ManyToOne(type => PowerUpEntity, powerUp => powerUp.factions)
+    powerUp: PowerUpEntity;
+    @OneToMany(type => FP_HistoryEntity, histories => histories.faction_PowerUp)
+    histories: FP_HistoryEntity[];
+  }
+  
+  @Entity('FP_History')
+  export class FP_HistoryEntity {
+    @PrimaryGeneratedColumn('uuid') historyId: string;
+    @Column({ type: 'timestamp' }) historyTimeStamp: Timestamp;
+  
+    @ManyToOne(
+      type => Faction_PowerUpEntity,
+      faction_PowerUp => faction_PowerUp.histories,
+    )
+    faction_PowerUp: Faction_PowerUpEntity;
+  }
+  
+  @Entity('Score')
+  export class ScoreEntity {
+    @PrimaryGeneratedColumn('uuid') scoreId: string;
+    @Column({ type: 'float' }) score: number;
+    @Column({ type: 'timestamp' }) scoreTimeStamp: Timestamp;
+  
+    @ManyToOne(type => FactionEntity, factionName => factionName.scores)
+    faction: FactionEntity;
+  }
+  
+  @Entity('Task')
+  export class TaskEntity {
+    @PrimaryGeneratedColumn('uuid') taskId: string;
+    @Column({ type: 'text' }) taskName: string;
+    @Column({ type: 'text' }) taskDescription: string;
+    @Column({ type: 'text' }) taskWinner: string;
+    @Column({ type: 'bool' }) taskIsActive: boolean;
+  
+    @ManyToOne(type => FactionEntity, faction => faction.tasks)
+    faction: FactionEntity;
+/*     @ManyToOne(type => PersonEntity, person => person.tasks)
+    person: PersonEntity; */
+  }
+  
\ No newline at end of file
diff --git a/src/game/game.controller.ts b/src/game/game.controller.ts
index bba49166a663fa07bfa4bcb75fbd3239a401564f..9eb94eb6bf4ed09c6a359c72daf8cfdcb0634079 100644
--- a/src/game/game.controller.ts
+++ b/src/game/game.controller.ts
@@ -1,49 +1,81 @@
-import { Controller, Post, UseGuards, Body, Get, Param, UsePipes, Put, Delete } from '@nestjs/common';
+import {
+  Controller,
+  Post,
+  UseGuards,
+  Body,
+  Get,
+  Param,
+  UsePipes,
+  Put,
+} from '@nestjs/common';
 
 import { GameService } from './game.service';
 import { AuthGuard } from '../shared/auth.guard';
 import { User } from '../user/user.decorator';
-import { GameDTO } from './game.dto';
+import { GameDTO, GameGroupDTO } from './game.dto';
 import { ValidationPipe } from '../shared/validation.pipe';
+import { Roles } from '../shared/roles.decorator';
 
 @Controller('game')
 export class GameController {
-    constructor(private gameservice: GameService) { }
+  constructor(private gameservice: GameService) {}
 
-    @Post('new')
-    @UseGuards(new AuthGuard())
-    @UsePipes(new ValidationPipe())
-    async newGame(@User('id') person, @Body() body: GameDTO ) {
-        return this.gameservice.createNewGame(person, body);
-    }
+  @Post('new')
+  @UseGuards(new AuthGuard())
+  @UsePipes(new ValidationPipe())
+  async newGame(@User('id') person, @Body() body: GameDTO) {
+    return this.gameservice.createNewGame(person, body);
+  }
 
-    @Put(':id')
-    @UseGuards(new AuthGuard())
-    @UsePipes(new ValidationPipe())
-    async editGame(@Param('id') id: string, @Body() body: GameDTO) {
-        return this.gameservice.editGame(id, body);
-    }
+  @Put(':id')
+  @Roles('admin')
+  @UsePipes(new ValidationPipe())
+  async editGame(@Param('id') id: string, @Body() body: GameDTO) {
+    return this.gameservice.editGame(id, body);
+  }
 
-    @Delete(':id')
-    @UseGuards(new AuthGuard())
-    async deleteGame(@Param('id') id) {
-        return this.gameservice.deleteGame(id);
-    }
+  @Post(':id')
+  @UseGuards(new AuthGuard())
+  @UsePipes(new ValidationPipe())
+  async createGroup(@User('id') person, @Param('id') id: string, @Body() data: GameGroupDTO) {
+    try {
+      return this.gameservice.createGroup(person, id, data);
+    } catch (error) {}
+  }
 
-    @UseGuards(new AuthGuard())
-    @UsePipes(new ValidationPipe())
-    @Post(':id')
-    async joinGame(@User('id') person, @Param('id') id: string, @Body() password: string) {
-        return this.gameservice.joinGame(person, id, password);
-    }
+  @Get('get-groups')
+  async getGroups() {
+    return this.gameservice.showGroups();
+  }
 
-    @Get('listgames')
-    async listGames() {
-        return this.gameservice.listGames();
-    }
+  @Put('groups/:id')
+  @UseGuards(new AuthGuard())
+  async joinGroup(@User('id') person, @Param('id') id) {
+    return this.gameservice.joinGroup(person, id)
+  }
 
-    @Get(':id')
-    async returnGameInfo(@Param('id') id: string) {
-        return this.gameservice.returnGameInfo(id);
+  @Put('joinfaction')
+  @UseGuards(new AuthGuard())
+  joinFaction(
+    @User('id') person,
+    @Param('id') gameId,
+    @Param('faction') faction: string,
+    @Body() password: string,
+  ) {
+    try {
+      //   return this.gameservice.joinFaction(person, gameId, faction, password);
+    } catch (error) {
+      return error;
     }
+  }
+
+  @Get('listgames')
+  async listGames() {
+    return this.gameservice.listGames();
+  }
+
+  @Get(':id')
+  async returnGameInfo(@Param('id') id: string) {
+    return this.gameservice.returnGameInfo(id);
+  }
 }
diff --git a/src/game/game.dto.ts b/src/game/game.dto.ts
index 737a428ac63507bbe561724923e32db96b2a78d4..a5d43f5d624a7ff690d2a5e6fa6e2db4d45eaed1 100644
--- a/src/game/game.dto.ts
+++ b/src/game/game.dto.ts
@@ -22,14 +22,23 @@ export class GameDTO {
 
   @IsDate()
   @IsNotEmpty()
-  startDate: string;
-
-  @IsDate()
+  @Length(1, 255)
+  desc: string;
   @IsNotEmpty()
-  endDate: string;
-
-  @IsArray()
+  //@IsJSON()
+  center: JSON;
+  //@IsJSON()
+  // doesn't accept with IsJSON, WIP to get validation for map and center
+  // IsJSON checks with json.parse, expecting string
+  map?: JSON;
+  @IsDateString()
   @IsNotEmpty()
+  startdate: string;
+  @IsDateString()
+  @IsNotEmpty()
+  enddate: string;
+  // custom validation for array length (arr>min, arr<max)
+  //@Validate(ArrayLength, [4, 8])
   factions?: FactionDTO[];
 
   @IsArray()
@@ -44,53 +53,15 @@ export class GameDTO {
 export class FactionDTO {
   @IsString()
   @IsNotEmpty()
-  @Length(3, 30)
-  factionName: string;
-
-  @IsString()
-  @IsNotEmpty()
-  @Length(3, 255)
-  faction_Password?: string;
-}
-
-/*export class PowerUpDTO {
-    @IsString() @IsNotEmpty()
-    powerUpName: string;
-
-    @IsString() @IsNotEmpty()
-    powerUpDescription?: string;
-
-    @IsInt() @IsNotEmpty()
-    amount: number;
-
-    @IsNotEmpty()
-    cooldown: string;
-}*/
-
-export class ObjectivePointDTO {
-  @IsString()
-  @IsNotEmpty()
-  objectivePointDescription: string;
-
-  @IsJSON()
-  @IsNotEmpty()
-  objectivePointCoordinates: JSON;
-
-  @IsArray()
-  @IsNotEmpty()
-  objectivePointHistory: ObjectivePointHistoryDTO[];
+  @Length(2, 15)
+  name: string;
+  id: string;
+  game: GameDTO;
+  password: string;
 }
 
-export class ObjectivePointHistoryDTO {
+export class GameGroupDTO {
   @IsString()
-  factionId: string;
-
-  @IsNotEmpty()
-  @IsInt()
-  @Min(0)
-  @Max(2)
-  oP_HistoryStatus: number;
-
-  @IsNotEmpty()
-  oP_HistoryTimestamp: Timestamp;
+  @Length(3, 31)
+  name: string;
 }
diff --git a/src/game/game.entity.ts b/src/game/game.entity.ts
index 9b499bb53fcb15dc7d8bc9019b347961066c0f9f..33b0a3acb8961a30dfad185fe42ca7903f2b2a47 100644
--- a/src/game/game.entity.ts
+++ b/src/game/game.entity.ts
@@ -5,16 +5,14 @@ import {
   ManyToOne,
   OneToMany,
   Timestamp,
-  PrimaryColumn,
+  OneToOne,
+  JoinColumn,
 } from 'typeorm';
-import { PersonEntity, PersonRoleEntity } from '../user/user.entity';
-import { FactionEntity } from '../game/faction.entity';
-import {
-  CoordinateEntity,
-  MapEntity,
-  MapDrawingEntity,
-  MapDrawingTypeEntity,
-} from './coordinate.entity';
+
+import { PersonEntity } from '../user/user.entity';
+import { GameGroupEntity } from './group.entity';
+import { FactionEntity } from './faction.entity';
+import { MapDrawingEntity } from './coordinate.entity';
 
 // table that stores all created games
 @Entity('Game')
@@ -23,22 +21,22 @@ export class GameEntity {
   @Column('text') name: string;
   @Column('text') desc: string;
   @Column('json') center: JSON;
-  @Column('json') map: JSON;
+  @Column({ type: 'json', nullable: true }) map: JSON;
   @Column('timestamp') startdate: Timestamp;
   @Column('timestamp') enddate: Timestamp;
-
-  @ManyToOne(type => MapEntity, map => map.games)
-  gamemap: MapEntity;
   @OneToMany(type => FactionEntity, faction => faction.game)
   factions: FactionEntity[];
   @OneToMany(type => Game_PersonEntity, game_persons => game_persons.game)
   game_persons: Game_PersonEntity[];
+  @OneToMany(type => GameGroupEntity, group => group.game)
+  groups: GameGroupEntity[];
   @OneToMany(
     type => ObjectivePointEntity,
     objective_points => objective_points.game,
   )
   objective_points: ObjectivePointEntity[];
 
+
   gameObject() {
     const { id, name } = this;
     return { id, name };
@@ -48,20 +46,24 @@ export class GameEntity {
 // table that stores players associated with particular game
 @Entity('Game_Person')
 export class Game_PersonEntity {
-  @PrimaryGeneratedColumn('uuid') gameId: string;
+  @PrimaryGeneratedColumn('uuid') gamepersonId: string;
+  @Column({ type: 'text', nullable: true }) role: string;
   @ManyToOne(type => FactionEntity, faction => faction.game_persons)
   faction: FactionEntity;
   @ManyToOne(type => GameEntity, game => game.game_persons)
   game: GameEntity;
   @ManyToOne(type => PersonEntity, person => person.game_persons)
   person: PersonEntity;
-  @ManyToOne(type => PersonRoleEntity, person_role => person_role.game_persons)
-  person_role: PersonRoleEntity;
-  @ManyToOne(
-    type => CoordinateEntity,
-    game_person_coordinates => game_person_coordinates.game_persons,
-  )
-  game_person_coordinates: CoordinateEntity;
+  @OneToOne(type => GameGroupEntity, group => group.leader, {
+    onDelete: 'CASCADE'
+  })
+  @JoinColumn({name: 'leaderGroup'})
+  leaderGroup: GameGroupEntity;
+  @ManyToOne(type => GameGroupEntity, group => group.players, {
+    onDelete: 'CASCADE'
+  })
+  @JoinColumn({name: 'group'})
+  group: GameGroupEntity;
 }
 
 @Entity('ObjectivePoint')
@@ -70,11 +72,8 @@ export class ObjectivePointEntity {
   @Column({ type: 'text' }) objectivePointDescription: string;
   @Column({ type: 'float' }) objectivePointMultiplier: number;
 
-  @ManyToOne(
-    type => CoordinateEntity,
-    coordinate => coordinate.objective_points,
-  )
-  coordinate: CoordinateEntity;
+  @ManyToOne(type => MapDrawingEntity, coordinate => coordinate.data)
+  coordinate: MapDrawingEntity;
   @ManyToOne(type => GameEntity, game => game.objective_points)
   game: GameEntity;
   @OneToMany(
@@ -96,62 +95,3 @@ export class ObjectivePoint_HistoryEntity {
   )
   objective_point: ObjectivePointEntity;
 }
-
-@Entity('PowerUp')
-export class PowerUpEntity {
-  @PrimaryGeneratedColumn('uuid') powerUpId: string;
-  @Column({ type: 'text' }) powerUpName: string;
-  @Column({ type: 'text' }) powerUpDescription: string;
-  @Column({ type: 'int' }) amount: number;
-  @Column({ type: 'time' }) cooldown: string;
-
-  @OneToMany(type => FactionEntity, factions => factions.powerUps)
-  factions: Faction_PowerUpEntity[];
-}
-
-@Entity('Faction_PowerUp')
-export class Faction_PowerUpEntity {
-  @PrimaryGeneratedColumn('uuid') faction_powerUpId: string;
-
-  @ManyToOne(type => FactionEntity, faction => faction.powerUps)
-  faction: FactionEntity;
-  @ManyToOne(type => PowerUpEntity, powerUp => powerUp.factions)
-  powerUp: PowerUpEntity;
-  @OneToMany(type => FP_HistoryEntity, histories => histories.faction_PowerUp)
-  histories: FP_HistoryEntity[];
-}
-
-@Entity('FP_History')
-export class FP_HistoryEntity {
-  @PrimaryGeneratedColumn('uuid') historyId: string;
-  @Column({ type: 'timestamp' }) historyTimeStamp: Timestamp;
-
-  @ManyToOne(
-    type => Faction_PowerUpEntity,
-    faction_PowerUp => faction_PowerUp.histories,
-  )
-  faction_PowerUp: Faction_PowerUpEntity;
-}
-@Entity('Score')
-export class ScoreEntity {
-  @PrimaryGeneratedColumn('uuid') scoreId: string;
-  @Column({ type: 'float' }) score: number;
-  @Column({ type: 'timestamp' }) scoreTimeStamp: Timestamp;
-
-  @ManyToOne(type => FactionEntity, factionName => factionName.scores)
-  faction: FactionEntity;
-}
-
-@Entity('Task')
-export class TaskEntity {
-  @PrimaryGeneratedColumn('uuid') taskId: string;
-  @Column({ type: 'text' }) taskName: string;
-  @Column({ type: 'text' }) taskDescription: string;
-  @Column({ type: 'text' }) taskWinner: string;
-  @Column({ type: 'bool' }) taskIsActive: boolean;
-
-  @ManyToOne(type => FactionEntity, faction => faction.tasks)
-  faction: FactionEntity;
-  @ManyToOne(type => PersonEntity, person => person.tasks)
-  person: PersonEntity;
-}
diff --git a/src/game/game.module.ts b/src/game/game.module.ts
index f51261d980a9eee78ddacd910c2d5f0f7e2e49c8..7df189f348bf12543437ecdd85d892980115c7ae 100644
--- a/src/game/game.module.ts
+++ b/src/game/game.module.ts
@@ -4,18 +4,12 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 import { GameController } from './game.controller';
 import { GameService } from './game.service';
 import { GameEntity, Game_PersonEntity } from './game.entity';
-import { FactionEntity } from './faction.entity';
 import { PersonEntity } from '../user/user.entity';
+import { GameGroupEntity } from './group.entity';
+import { FactionEntity } from './faction.entity';
 
 @Module({
-  imports: [
-    TypeOrmModule.forFeature([
-      GameEntity,
-      FactionEntity,
-      Game_PersonEntity,
-      PersonEntity,
-    ]),
-  ],
+  imports: [TypeOrmModule.forFeature([GameEntity, FactionEntity, Game_PersonEntity, PersonEntity, GameGroupEntity])],
   controllers: [GameController],
   providers: [GameService],
 })
diff --git a/src/game/game.service.ts b/src/game/game.service.ts
index 58419ebc611c9afc8ac65d3f651dd83865043bc5..8dbc824e5d91b2ec9d9e1da54cbdd90a53e1ea96 100644
--- a/src/game/game.service.ts
+++ b/src/game/game.service.ts
@@ -1,11 +1,12 @@
-import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
+import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
 import { InjectRepository } from '@nestjs/typeorm';
-import { Repository, In } from 'typeorm';
+import { Repository, Not } from 'typeorm';
 
 import { GameEntity, Game_PersonEntity } from './game.entity';
-import { FactionEntity } from './faction.entity';
 import { GameDTO } from './game.dto';
 import { PersonEntity } from '../user/user.entity';
+import { GameGroupEntity } from './group.entity';
+import { FactionEntity } from './faction.entity';
 
 @Injectable()
 export class GameService {
@@ -18,51 +19,77 @@ export class GameService {
     private personRepository: Repository<PersonEntity>,
     @InjectRepository(Game_PersonEntity)
     private game_PersonRepository: Repository<Game_PersonEntity>,
+    @InjectRepository(GameGroupEntity)
+    private game_GroupRepository: Repository<GameGroupEntity>,
   ) {}
 
   // create a new game
-  async createNewGame(personId: string, gameData: GameDTO) {
+  async createNewGame(personId: PersonEntity, gameData: GameDTO) {
+    try {
+      // checks if a game with the same name exists already
+      const { name } = gameData;
+      if (await this.gameRepository.findOne({ where: { name } })) {
+        throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
+      }
+      // else add the game to the database
+      const game = await this.gameRepository.create({
+        ...gameData,
+        factions: gameData.factions,
+      });
+      await this.gameRepository.insert(game);
+      const gamePerson = await this.game_PersonRepository.create({
+        faction: null,
+        game: game,
+        person: personId,
+      });
+      gamePerson['role'] = 'admin';
+      await this.game_PersonRepository.insert(gamePerson);
+      return {
+        message: 'New game added',
+      };
+    } catch (error) {
+      return error.message;
+    }
+  }
+
+  // edit already created game
+  async editGame(id: string, gameData: GameDTO) {
     // checks if a game with the same name exists already
     const { name } = gameData;
-    if (await this.gameRepository.findOne({ where: { name } })) {
+    if (await this.gameRepository.findOne({ name: name, id: Not(id) })) {
       throw new HttpException('Game already exists', HttpStatus.BAD_REQUEST);
     }
-    // else add the game to the database
-    const game = await this.gameRepository.create({
+    // update game entry in db
+    const updatedGame = await this.gameRepository.create({
       ...gameData,
       factions: gameData.factions,
     });
-    await this.gameRepository.insert(game);
-    return {
-      message: 'New game added',
-    };
-  }
+    updatedGame['id'] = id;
+    const gameId = await this.gameRepository.save(updatedGame);
 
-  // edit already created game
-  async editGame(id: string, gameData: Partial<GameDTO>) {
-    try {
-      // update game entry in db
-      let update = await this.gameRepository.create({
-        ...gameData,
-        factions: gameData.factions,
-      });
-      await this.gameRepository.update({ id }, update);
-      // add the factions to db
-      if (gameData.factions) {
-        gameData.factions.map(async faction => {
+    // get all the factions that are associated with the game to deny duplicate entries
+    const factions = await this.factionRepository.find({
+      select: ['factionName'],
+      where: { game: gameId },
+    });
+    const factionNames = factions.map(({ factionName }) => factionName);
+
+    // add the factions to db
+    if (gameData.factions) {
+      gameData.factions.map(async faction => {
+        if (!Object.values(factionNames).includes(faction.name)) {
           let name = await this.factionRepository.create({
             ...faction,
-            game: gameData,
+            game: gameId,
           });
           await this.factionRepository.insert(name);
-        });
-      }
-      return {
-        message: 'Game updated',
-      };
-    } catch (error) {
-      console.log(error);
+        }
+      });
     }
+
+    return {
+      message: 'Game updated',
+    };
   }
 
   async deleteGame(id) {
@@ -74,22 +101,76 @@ export class GameService {
   }
 
   // checks the password, creates an entry in GamePerson table with associated role&faction
-  async joinGame(person, gameId, json) {
-    const user = await this.personRepository.findOne({
-      where: { id: person },
-    });
-    const game = await this.gameRepository.findOne({ where: { id: gameId } });
+  async createGroup(person, gameId, groupData) {
+    try {
+      // check if the person already is in a group in this game
+      const checkDuplicate = await this.game_PersonRepository.findOne({
+        person: person,
+      });
+      if (checkDuplicate) {
+        throw new HttpException(
+          'You already belong to a group!',
+          HttpStatus.BAD_REQUEST,
+        );
+      }
 
-    //const index = game.passwords.indexOf(json.password);
+      // create a group entry and insert it to db
+      const group = await this.game_GroupRepository.create({
+        ...groupData,
+        game: gameId,
+      });
+      const gameGroup = await this.game_GroupRepository.insert(group);
 
-    // create game_Person entry
-    /*     const gamePerson = await this.game_PersonRepository.create({
-      faction,
-      gameId,
-      person,
-    });
-    */
-    return 'WIP';
+      // create game_Person entry and insert it to db
+      const gamePerson = await this.game_PersonRepository.create({
+        role: 'soldier',
+        faction: null,
+        game: gameId,
+        person: person,
+        leaderGroup: gameGroup.identifiers[0]['id'],
+        group: gameGroup.identifiers[0]['id'],
+      });
+      await this.game_PersonRepository.insert(gamePerson);
+
+      return {
+        message: 'created new group',
+      };
+    } catch (e) {
+      return e;
+    }
+  }
+
+  async showGroups() {
+    try {
+      return await this.game_GroupRepository.find({
+        relations: ['leader', 'players', 'game'],
+      });
+    } catch (e) {
+      return e;
+    }
+  }
+
+  async joinGroup(person, groupId) {
+    try {
+      const gameData = await this.game_GroupRepository.findOne({
+        where: { id: groupId },
+        relations: ['players', 'game'],
+      });
+      const gamePerson = await this.game_PersonRepository.create({
+        role: 'soldier',
+        faction: null,
+        game: gameData.game,
+        person: person,
+        leaderGroup: null,
+        group: groupId,
+      });
+      await this.game_PersonRepository.insert(gamePerson);
+      return {
+        message: 'Joined group',
+      };
+    } catch (e) {
+      return e;
+    }
   }
 
   // returns name and id of each game
diff --git a/src/game/group.entity.ts b/src/game/group.entity.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0b9f00ed621b41b8515a77126f9564c14a02d74b
--- /dev/null
+++ b/src/game/group.entity.ts
@@ -0,0 +1,28 @@
+import {
+    Entity,
+    Column,
+    PrimaryGeneratedColumn,
+    ManyToOne,
+    OneToMany,
+    OneToOne,
+    JoinColumn,
+  } from 'typeorm';
+  
+import { Game_PersonEntity, GameEntity } from './game.entity';
+
+@Entity('GameGroup')
+export class GameGroupEntity {
+  @PrimaryGeneratedColumn('uuid') id: string;
+  @Column('text') name: string;
+  @OneToOne(type => Game_PersonEntity, person => person.leaderGroup, {
+      onDelete: 'CASCADE'
+  })
+  //@JoinColumn({name:'leader'})
+  leader: Game_PersonEntity;
+  @OneToMany(type => Game_PersonEntity, person => person.group, {
+      onDelete: 'CASCADE'
+  })
+  players: Game_PersonEntity[];
+  @ManyToOne(type => GameEntity, game => game.groups)
+  game: GameEntity;
+}
\ No newline at end of file
diff --git a/src/main.ts b/src/main.ts
index 3c7cc4607bac085ff529775a441ef81e4e089a6a..1e3e4e147bc386a4ce15a36bf274face5fd14c1e 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,6 +3,11 @@ import * as rateLimit from 'express-rate-limit';
 
 import { AppModule } from './app.module';
 
+
+/*
+  Main.ts starts the server.
+*/
+
 // due to a bug with newest release of express-rate-limit, call for rateLimit is broken
 // (rateLimit as any) works as a workaround for now
 // see https://github.com/nfriedly/express-rate-limit/issues/138
diff --git a/src/mapmarkers/mapmarker.entity.ts b/src/mapmarkers/mapmarker.entity.ts
index bc6d33112149f23e52e493c374be19ca0f18e536..b83b1d9ad56c6de51563aa0e1a5fe024e5cf9665 100644
--- a/src/mapmarkers/mapmarker.entity.ts
+++ b/src/mapmarkers/mapmarker.entity.ts
@@ -1,19 +1,26 @@
-import { Entity, Column, PrimaryGeneratedColumn, Timestamp, ManyToOne } from 'typeorm';
-
-import { PersonEntity } from '../user/user.entity'
-
-/*
-Entity: MapMarker 
-- represents data that database contains on mapmarker
-*/
-
-@Entity('MapMarker')
-export class MapMarkerEntity {
+import {
+    Entity,
+    Column,
+    PrimaryGeneratedColumn,
+    Timestamp,
+    ManyToOne,
+  } from 'typeorm';
+  
+  import { PersonEntity } from '../user/user.entity';
+  
+  /*
+  Entity: MapMarker 
+  - represents data that database contains on mapmarker
+  */
+  
+  @Entity('MapMarker')
+  export class MapMarkerEntity {
     @PrimaryGeneratedColumn('uuid') id: string;
-    @Column({type: 'text'}) latitude: string;
-    @Column({type: 'text'}) longitude: string;
-    @Column({type: 'timestamp'}) timestamp: Timestamp;
-    @Column({type: 'json', nullable: true}) features: JSON;
+    @Column({ type: 'text', nullable: true }) latitude: string;
+    @Column({ type: 'text', nullable: true }) longitude: string;
+    @Column({ type: 'timestamp' }) timestamp: Timestamp;
+    @Column({ type: 'json', nullable: true }) features: JSON;
     @ManyToOne(type => PersonEntity, player => player.markers)
     player: PersonEntity;
-}
\ No newline at end of file
+  }
+  
\ No newline at end of file
diff --git a/src/mapmarkers/mapmarker.service.ts b/src/mapmarkers/mapmarker.service.ts
index 9e0167075f46f6d68a34afa0f5bc421e21699d7e..1a948694810e6ba42b961bde7bd73de02ba24fb6 100644
--- a/src/mapmarkers/mapmarker.service.ts
+++ b/src/mapmarkers/mapmarker.service.ts
@@ -1,6 +1,6 @@
 import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
-import { Repository, In } from "typeorm";
-import { InjectRepository } from "@nestjs/typeorm";
+import { Repository, In } from 'typeorm';
+import { InjectRepository } from '@nestjs/typeorm';
 
 import { MapMarkerEntity } from './mapmarker.entity';
 import { MapMarkerDTO } from './mapmarker.dto';
@@ -9,41 +9,50 @@ import { userInfo } from 'os';
 
 @Injectable()
 export class MapMarkerService {
-    constructor(
-        //create references to tables as repositories
-        @InjectRepository(MapMarkerEntity) private mapmarkerRepository: Repository<MapMarkerEntity>,
-        @InjectRepository(PersonEntity) private personRepository: Repository<PersonEntity>
-    ) { }
+  constructor(
+    //create references to tables as repositories
+    @InjectRepository(MapMarkerEntity)
+    private mapmarkerRepository: Repository<MapMarkerEntity>,
+    @InjectRepository(PersonEntity)
+    private personRepository: Repository<PersonEntity>,
+  ) {}
 
-    // insert markers
-    async insertLocation(personId: string, data: MapMarkerDTO) {
-        try {
-           
-            //get functions runtime as timestamp
-            data.timestamp = new Date(Date.now()).toLocaleString(); 
-            //check from database for the user who uploads the data
-            const user = await this.personRepository.findOne({ where: { id: personId } })
-            //create&copy entity properties
-            const location = await this.mapmarkerRepository.create({ ...data, player: user });
-            // insert created entity NOTE: insert method doesn't check for duplicates.
-            await this.mapmarkerRepository.insert(location);
-            // return data and player id&name
-            return { ...data, player: location.player.nameObject() };
-        } catch (error) {
-            return error;
-        }
+  // insert marker
+  async insertLocation(personId: string, data: MapMarkerDTO) {
+    try {
+      //get functions runtime as timestamp
+      data.timestamp = new Date(Date.now()).toLocaleString();
+      //check from database for the user who uploads the data
+      const user = await this.personRepository.findOne({
+        where: { id: personId },
+      });
+      //create&copy entity properties
+      const location = await this.mapmarkerRepository.create({
+        ...data,
+        player: user,
+      });
+      // insert created entity NOTE: insert method doesn't check for duplicates.
+      await this.mapmarkerRepository.insert(location);
+      // return data and player id&name
+      return { ...data, player: location.player.nameObject() };
+    } catch (error) {
+      return error;
     }
+  }
 
-    // get all markers
-    async getAllMarkers() {
-        try {
-            // find all markers with specified player
-            const markers = await this.mapmarkerRepository.find({ relations: ['player'] });
-            // return markers from database with said playerdata
-            return markers.map(marker => { return { ...marker, player: marker.player.nameObject() } });
-        } catch (error) {
-            return error.message;
-        }
-
+  // get all markers
+  async getAllMarkers() {
+    try {
+      // find all markers with specified player
+      const markers = await this.mapmarkerRepository.find({
+        relations: ['player'],
+      });
+      // return markers from database with said playerdata
+      return markers.map(marker => {
+        return { ...marker, player: marker.player.nameObject() };
+      });
+    } catch (error) {
+      return error.message;
     }
-}
\ No newline at end of file
+  }
+}
diff --git a/src/mapmarkers/mapmarkers.controller.ts b/src/mapmarkers/mapmarkers.controller.ts
index 58c4035753abd25239ba44623fb227d628c3c4d9..fef971652de596196169251c202378c67902babd 100644
--- a/src/mapmarkers/mapmarkers.controller.ts
+++ b/src/mapmarkers/mapmarkers.controller.ts
@@ -23,6 +23,10 @@ export class MapMarkersController {
     // return all markers through service
     @Get('getall')
     async getAll(){
-        return this.mapmarkerservice.getAllMarkers();
+        try{
+            return this.mapmarkerservice.getAllMarkers();
+        }catch(error){
+            return error.message;
+        }
     }
 }
diff --git a/src/shared/auth.guard.ts b/src/shared/auth.guard.ts
index 78d66f86757f1f5803338440839afeb3610ed1d7..ff2bdf406d5badffc467cdf22d0f61935aae0af8 100644
--- a/src/shared/auth.guard.ts
+++ b/src/shared/auth.guard.ts
@@ -1,30 +1,43 @@
-import { Injectable, ExecutionContext, CanActivate, HttpException, HttpStatus } from '@nestjs/common';
+import {
+  Injectable,
+  ExecutionContext,
+  CanActivate,
+  HttpException,
+  HttpStatus,
+} from '@nestjs/common';
 import * as jwt from 'jsonwebtoken';
 
 @Injectable()
 export class AuthGuard implements CanActivate {
+  // check for logged in user
+  async canActivate(context: ExecutionContext): Promise<boolean> {
+    // get request
+    const request = context.switchToHttp().getRequest();
+    // check for authorization header
+    if (!request.headers.authorization) {
+      return false;
+    }
 
-    async canActivate(context: ExecutionContext): Promise<boolean> {
-        const request = context.switchToHttp().getRequest();
-        if (!request.headers.authorization) {
-            return false;
-        }
+    // validate token
+    request.user = await this.validateToken(request.headers.authorization);
 
-        request.user = await this.validateToken(request.headers.authorization);
+    return true;
+  }
 
-        return true;
+  // validate token
+  async validateToken(auth: string) {
+    // check if header contains Bearer
+    if (auth.split(' ')[0] !== 'Bearer') {
+      throw new HttpException('Invalid token', HttpStatus.FORBIDDEN);
     }
-
-    async validateToken(auth: string) {
-        if (auth.split(" ")[0] !== 'Bearer') {
-            throw new HttpException('Invalid token', HttpStatus.FORBIDDEN);
-        }
-        const token = auth.split(" ")[1];
-        try {
-            return await jwt.verify(token, process.env.SECRET); 
-        } catch (err) {
-            const message = `Token error: ${err.message || err.name}`
-            throw new HttpException(message, HttpStatus.FORBIDDEN);
-        }
+    // get the token
+    const token = auth.split(' ')[1];
+    try {
+      // return token.
+      return await jwt.verify(token, process.env.SECRET);
+    } catch (err) {
+      const message = `Token error: ${err.message || err.name}`;
+      throw new HttpException(message, HttpStatus.FORBIDDEN);
     }
-}
\ No newline at end of file
+  }
+}
diff --git a/src/shared/roles.decorator.ts b/src/shared/roles.decorator.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0d14223c3ce5ee1002cf245fa16fd1b57749bae1
--- /dev/null
+++ b/src/shared/roles.decorator.ts
@@ -0,0 +1,3 @@
+import { SetMetadata } from '@nestjs/common';
+
+export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
\ No newline at end of file
diff --git a/src/shared/roles.guard.ts b/src/shared/roles.guard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1f05fc90d4c008277e96d543f8112b4581a91c47
--- /dev/null
+++ b/src/shared/roles.guard.ts
@@ -0,0 +1,51 @@
+import {
+  Injectable,
+  CanActivate,
+  ExecutionContext,
+  HttpException,
+  HttpStatus,
+} from '@nestjs/common';
+import { Reflector } from '@nestjs/core';
+import * as jwt from 'jsonwebtoken';
+import { InjectRepository } from '@nestjs/typeorm';
+import { Repository } from 'typeorm';
+
+import { Game_PersonEntity } from '../game/game.entity';
+
+@Injectable()
+export class RolesGuard implements CanActivate {
+  constructor(
+    private readonly reflector: Reflector,
+    @InjectRepository(Game_PersonEntity)
+    private game_PersonRepository: Repository<Game_PersonEntity>,
+    ) {}
+
+  async canActivate(context: ExecutionContext): Promise<boolean> {
+    // get roles that are allowed access, identified by @Roles('role') decorators in controllers
+    const roles = this.reflector.get<string[]>('roles', context.getHandler());
+    if (!roles) {
+      return true;
+    }
+    const request = context.switchToHttp().getRequest();
+    const gameId = request.params.id
+    const user = await this.getUserObject(request.headers.authorization);
+    const role = await this.game_PersonRepository.findOne({person: user['id'], game: gameId})
+    // check that the role matches the criteria and that token is valid for this game
+    return role && roles.includes(role['role']);
+  }
+
+  async getUserObject(auth: string) {
+    // check if header contains Bearer
+    if (auth.split(' ')[0] !== 'Bearer') {
+      throw new HttpException('Invalid token', HttpStatus.FORBIDDEN);
+    }
+    // get the token
+    const token = auth.split(' ')[1];
+    try {
+      return await jwt.verify(token, process.env.SECRET)
+    } catch (err) {
+      const message = `Token error: ${err.message || err.name}`;
+      throw new HttpException(message, HttpStatus.FORBIDDEN);
+    }
+  }
+}
diff --git a/src/user/user.controller.ts b/src/user/user.controller.ts
index 2910ed9c445715f94c698935428bf2c85ef6d717..4d4158d3f037850c8c5230975ef5f46ae5a75ede 100644
--- a/src/user/user.controller.ts
+++ b/src/user/user.controller.ts
@@ -1,4 +1,11 @@
-import { Controller, Post, Body, UsePipes, Get, UseGuards } from '@nestjs/common';
+import {
+  Controller,
+  Post,
+  Body,
+  UsePipes,
+  Get,
+  UseGuards,
+} from '@nestjs/common';
 
 import { UserService } from './user.service';
 import { UserDTO } from './user.dto';
@@ -7,24 +14,24 @@ import { ValidationPipe } from '../shared/validation.pipe';
 
 @Controller('user')
 export class UserController {
-    constructor(private userService: UserService) { }
+  constructor(private userService: UserService) {}
 
-    @Post('register')
-    @UsePipes(new ValidationPipe())
-    createUser(@Body() data: UserDTO) {
-        return this.userService.register(data);
-    }
+  @Post('register')
+  @UsePipes(new ValidationPipe())
+  createUser(@Body() data: UserDTO) {
+    return this.userService.register(data);
+  }
 
-    @Post('login')
-    @UsePipes(new ValidationPipe())
-    loginUser(@Body() data: UserDTO) {
-        return this.userService.login(data);
-    }
+  @Post('login')
+  @UsePipes(new ValidationPipe())
+  loginUser(@Body() data: UserDTO) {
+    return this.userService.login(data);
+  }
 
-    // verifies the token
-    @Get('verify')
-    @UseGuards(new AuthGuard())
-    showMap() {
-        return true;
-    }
+  // verifies the token
+  @Get('verify')
+  @UseGuards(new AuthGuard())
+  showMap() {
+    return true;
+  }
 }
diff --git a/src/user/user.entity.ts b/src/user/user.entity.ts
index a1a33a09e6dad6fad6979a1ae7cf9ed270e0453f..6323836fdcaf3fbd91a3be97268e9a659e142b41 100644
--- a/src/user/user.entity.ts
+++ b/src/user/user.entity.ts
@@ -1,4 +1,10 @@
-import { Entity, Column, PrimaryGeneratedColumn, BeforeInsert, OneToMany } from 'typeorm';
+import {
+  Entity,
+  Column,
+  PrimaryGeneratedColumn,
+  BeforeInsert,
+  OneToMany,
+} from 'typeorm';
 import * as bcrypt from 'bcryptjs';
 import * as jwt from 'jsonwebtoken';
 import { MapMarkerEntity } from 'src/mapmarkers/mapmarker.entity';
@@ -7,54 +13,45 @@ import {Game_PersonEntity} from '../game/game.entity'
 
 @Entity('Person')
 export class PersonEntity {
-    @PrimaryGeneratedColumn('uuid') id: string;
-    @Column({type: 'text', unique: true}) name: string;
-    @Column('text') password: string;
-    @OneToMany(type => MapMarkerEntity, marker => marker.player)
-    markers: MapMarkerEntity[];
-    @OneToMany(type => TaskEntity, task => task.person)
-    tasks: TaskEntity[];
-    @OneToMany(type => Game_PersonEntity, game_persons => game_persons.person)
-    game_persons: Game_PersonEntity[];
-
-    // hashes the password before inserting it to database
-    @BeforeInsert()
-    async hashPassword() {
-        this.password = await bcrypt.hash(this.password, 10);
-    }
-
-    // returns username and associated token
-    tokenObject() {
-        const {name, token} = this;
-        return {name, token};
-    }
-
-    // returns username and the id
-    nameObject() {
-        const {id, name} = this;
-        return {id, name};
-    }
-
-    async comparePassword(attempt: string) {
-        return await bcrypt.compareSync(attempt, this.password);
-    }
-
-    private get token() {
-        const {id, name} = this;
-        return jwt.sign({
-            id, name
-        },
-        process.env.SECRET,
-        { expiresIn: '7d'},
-        );
-    }
+  @PrimaryGeneratedColumn('uuid') id: string;
+  @Column({ type: 'text', unique: true }) name: string;
+  @Column('text') password: string;
+  @OneToMany(type => MapMarkerEntity, marker => marker.player)
+  markers: MapMarkerEntity[];
+  @OneToMany(type => Game_PersonEntity, game_persons => game_persons.person)
+  game_persons: Game_PersonEntity[];
+
+  // hashes the password before inserting it to database
+  @BeforeInsert()
+  async hashPassword() {
+    this.password = await bcrypt.hash(this.password, 10);
+  }
+
+  // returns username and associated token
+  tokenObject() {
+    const { name, token } = this;
+    return { name, token };
+  }
+
+  // returns username and the id
+  nameObject() {
+    const { id, name } = this;
+    return { id, name };
+  }
+
+  async comparePassword(attempt: string) {
+    return await bcrypt.compareSync(attempt, this.password);
+  }
+
+  private get token() {
+    const { id, name } = this;
+    return jwt.sign(
+      {
+        id,
+        name,
+      },
+      process.env.SECRET,
+      { expiresIn: '7d' },
+    );
+  }
 }
-
-@Entity('PersonRole')
-export class PersonRoleEntity {
-    @PrimaryGeneratedColumn('uuid') person_roleId: string;
-    @Column({type: 'text'}) person_roleDescription: string;
-
-    @OneToMany(type => Game_PersonEntity, game_persons => game_persons.person_role)
-    game_persons: Game_PersonEntity[];
-}
\ No newline at end of file
diff --git a/src/user/user.module.ts b/src/user/user.module.ts
index cd43a16b6f27fc11b6c277617f859889021b0c5a..6cb77a7b735df532d710febc33a4df53f264563a 100644
--- a/src/user/user.module.ts
+++ b/src/user/user.module.ts
@@ -3,11 +3,12 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 
 import { UserController } from './user.controller';
 import { UserService } from './user.service';
-import { PersonEntity } from './user.entity';
+import { PersonEntity} from './user.entity';
+import { GameEntity } from '../game/game.entity';
 
 @Module({
-  imports: [TypeOrmModule.forFeature([PersonEntity])],
+  imports: [TypeOrmModule.forFeature([PersonEntity, GameEntity])],
   controllers: [UserController],
-  providers: [UserService]
+  providers: [UserService],
 })
 export class UserModule {}
diff --git a/src/user/user.service.ts b/src/user/user.service.ts
index 0b42bf9689f1cf7a697baa5c0093e02105794e6a..8d0a64d8ea0430d1633e67a17ee3fb782d21ce72 100644
--- a/src/user/user.service.ts
+++ b/src/user/user.service.ts
@@ -4,10 +4,17 @@ import { InjectRepository } from "@nestjs/typeorm";
 
 import { PersonEntity } from './user.entity';
 import { UserDTO } from './user.dto';
+import { GameEntity } from '../game/game.entity';
+import { GameDTO } from '../game/game.dto';
 
 @Injectable()
 export class UserService {
-    constructor(@InjectRepository(PersonEntity) private userRepository: Repository<PersonEntity>){}
+    constructor(
+        @InjectRepository(PersonEntity) 
+        private userRepository: Repository<PersonEntity>,
+        @InjectRepository(GameEntity)
+        private gameRepository: Repository<GameEntity>
+        ){}
 
     async register(data: UserDTO) {
         const { name } = data;
@@ -21,14 +28,40 @@ export class UserService {
     }
 
     async login(data: UserDTO) {
-        const { name, password } = data;
-        const user = await this.userRepository.findOne({ where: { name }});
-        if (!user || !(await user.comparePassword(password))) {
-            throw new HttpException(
-                'Invalid username/password',
-                HttpStatus.BAD_REQUEST,
-            );
+        try{
+            const { name, password } = data;
+            const user = await this.userRepository.findOne({ where: { name }});
+            if (!user || !(await user.comparePassword(password))) {
+                throw new HttpException(
+                    'Invalid username/password',
+                    HttpStatus.BAD_REQUEST,
+                );
+            }
+            return user.tokenObject();
+        }catch(error){
+            return error.message;
+        }
+    }
+
+    // liitytään peliin
+    async joinGame(game: GameDTO, data: UserDTO){
+        try {
+            // etsi peli valinnan mukaan ja otetaan käyttäjän rooli kyseisestä pelistä talteen
+            const role = await this.gameRepository.findOne();
+            return role;
+        } catch (error) {
+            return error.message;
         }
-        return user.tokenObject();
     }
+
+    // liitytään factionii
+    async joinFaction(game: GameDTO, data: UserDTO): Promise<boolean>{
+        try {
+            // tarkistetaan factionin salasana
+            return true;
+        } catch (error) {
+            return error;
+        }
+    }
+
 }