diff --git a/backend/migrations-init/m241103_021658_target_api_url_routes.php b/backend/migrations-init/m241103_021658_target_api_url_routes.php index 20ea20fd9..77732847b 100644 --- a/backend/migrations-init/m241103_021658_target_api_url_routes.php +++ b/backend/migrations-init/m241103_021658_target_api_url_routes.php @@ -20,6 +20,7 @@ public function safeUp() $this->upsert('url_route',['source'=>'api/target//spin','destination'=>'api/target/spin','weight'=>645]); $this->upsert('url_route',['source'=>'api/target//spawn','destination'=>'api/target/spawn','weight'=>646]); $this->upsert('url_route',['source'=>'api/target//shut','destination'=>'api/target/shut','weight'=>647]); + $this->upsert('url_route',['source'=>'api/profile/me','destination'=>'api/profile/me','weight'=>648]); } /** diff --git a/docs/API.md b/docs/API.md index 27c4d24f7..61828f110 100644 --- a/docs/API.md +++ b/docs/API.md @@ -58,6 +58,7 @@ curl -i -H "Accept:application/json" "https://echoctf.red/api/headshots?filter[p ## Bearer Operations For the following endpoints you will need to have a bearer token to be able to access them +* `api/profile/me`: Get your profile details * `api/target/claim`: Submit a flag for validation * `api/target/instances`: List of instances (if any) * `api/target/`: Get details for a given target @@ -65,6 +66,15 @@ For the following endpoints you will need to have a bearer token to be able to a * `api/target//spawn`: Spawn a private instance (if allowed) * `api/target//shut`: Shutdown a private instance +### Get profile details +URL: `GET /api/profile/me` + +```sh +curl "https://echoctf.red/api/target/me" \ + -H "Authorization: Bearer YOURTOKEN" \ + -H "Accept:application/json" +``` + ### Claim Flag URL: `POST /api/target/claim` \ POST: `{ "hash":"flag" }` diff --git a/frontend/models/PlayerAR.php b/frontend/models/PlayerAR.php index 599dc1ace..2821a7c14 100644 --- a/frontend/models/PlayerAR.php +++ b/frontend/models/PlayerAR.php @@ -284,4 +284,9 @@ public function getMetadata() return $this->hasOne(PlayerMetadata::class, ['player_id' => 'id']); } + public function getPlayerLast() + { + return $this->hasOne(PlayerLast::class, ['id' => 'id']); + } + } diff --git a/frontend/modules/api/controllers/ProfileController.php b/frontend/modules/api/controllers/ProfileController.php new file mode 100644 index 000000000..a5670265f --- /dev/null +++ b/frontend/modules/api/controllers/ProfileController.php @@ -0,0 +1,82 @@ + 'yii\rest\Serializer', + 'collectionEnvelope' => 'items', + ]; + public function behaviors() + { + \Yii::$app->user->enableSession = false; + \Yii::$app->user->loginUrl = null; + + return ArrayHelper::merge(parent::behaviors(), [ + 'authenticator' => [ + 'authMethods' => [ + HttpBearerAuth::class, + ], + ], + 'content' => [ + 'class' => yii\filters\ContentNegotiator::class, + 'formats' => [ + 'application/json' => \yii\web\Response::FORMAT_JSON, + ], + ], + 'access' => [ + 'class' => AccessControl::class, + 'rules' => [ + [ //api_bearer_disable + 'allow' => false, + 'matchCallback' => function () { + return \Yii::$app->sys->api_bearer_enable !== true; + } + ], + [ + 'allow' => true, + 'roles' => ['@'], + ], + ], + ], + ]); + } + + public function actions() + { + $actions = parent::actions(); + // disable the "delete", "create", "view","update" actions + unset($actions['delete'], $actions['create'], $actions['update'], $actions['index'], $actions['view']); + + return $actions; + } + + public function actionMe() + { + $profile = array_merge(['id' => null, 'username' => Yii::$app->user->identity->username, 'bio' => null, 'vip' => null, 'admin' => null, 'onVPN' => null, 'vpn_ip' => null], Yii::$app->user->identity->profile->attributes); + unset( + $profile['gdpr'], + $profile['htb'], + $profile['terms_and_conditions'], + $profile['mail_optin'], + $profile['updated_at'], + $profile['approved_avatar'], + $profile['echoctf'], + $profile['player_id'], + $profile['created_at'], + ); + $profile['created_at'] = Yii::$app->user->identity->created; + $profile['vip'] = Yii::$app->user->identity->isVip; + $profile['admin'] = Yii::$app->user->identity->isAdmin; + $profile['onVPN'] = Yii::$app->user->identity->onVPN; + $profile['vpn_ip'] = Yii::$app->user->identity->vpnIP; + return $profile; + } +}