From 4a9924d174b1d7016ba9efaaa635e2f1705a0b5c Mon Sep 17 00:00:00 2001 From: Tsang Henry Date: Wed, 8 Aug 2018 23:59:24 +0800 Subject: [PATCH] auth --- .gitignore | 2 + README.md | 13 ++ composer.json | 20 +++ src/Auth/Controller/Login.php | 51 ++++++++ .../Exception/UserNameOrPasswordError.php | 16 +++ src/Auth/Model/User.php | 25 ++++ src/Common/Controller/ExtendController.php | 64 ++++++++++ src/Common/Exception/FilterFormatError.php | 15 +++ src/Common/Utility/Query.php | 119 ++++++++++++++++++ 9 files changed, 325 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 composer.json create mode 100644 src/Auth/Controller/Login.php create mode 100644 src/Auth/Exception/UserNameOrPasswordError.php create mode 100644 src/Auth/Model/User.php create mode 100644 src/Common/Controller/ExtendController.php create mode 100644 src/Common/Exception/FilterFormatError.php create mode 100644 src/Common/Utility/Query.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cac762f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +/.idea/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..92b61c2 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +UsingTrait +-------------- + +UsingTrait 是一个基于 Trait 实现的应用开发框架。 + + +### 约定 +* 所有表名和字段名使用下划线结构 +* Model使用驼峰结构 +* 表内自增ID字段为 id +* 外键使用 表名 + _id +* 当有多个外键指向相同表时,使用 prefix_ + 表名 + _id + diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..7536682 --- /dev/null +++ b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "usingnet/usingtrait", + "description": "Application framework base on trait", + "type": "library", + "license": "LGPL-v3", + "authors": [ + { + "name": "UsingTeam", + "email": "developer@usingnet.com" + } + ], + "prefer-stable": true, + "require": { + "php": ">=7.0.28", + "phalcon/cphalcon": ">=3.4.1" + }, + "autoload": { + "psr-4": {"UsingTrait\\": "src/"} + } +} diff --git a/src/Auth/Controller/Login.php b/src/Auth/Controller/Login.php new file mode 100644 index 0000000..92ed23c --- /dev/null +++ b/src/Auth/Controller/Login.php @@ -0,0 +1,51 @@ +loginIdentificationFields as $key=>$field){ + if(is_numeric($key)){ + $filter[$field] = $this->getPost($field); + }else{ + $filter[$key] = $this->getPost($field); + } + } + try { + $user = $this->getLoginModel()::findFirst(Query::filterToParameters($filter)); + if(!$user){ + return $this->responseError('Username or Password Error'); + } + if(!$user instanceof User){ + return $this->responseError(sprintf('getLoginModel should return an instance of UsingTrait\Auth\Model\User but taken a(n) ', get_class($user))); + } + if(!$user->verifyPassword($this->getPost('password'))){ + return $this->responseError('Username or Password Error'); + } + + return $this->responseOk($user); + } catch (FilterFormatError $e) { + return $this->responseError($e->getMessage(), $e->getCode()); + } + } +} \ No newline at end of file diff --git a/src/Auth/Exception/UserNameOrPasswordError.php b/src/Auth/Exception/UserNameOrPasswordError.php new file mode 100644 index 0000000..5237f44 --- /dev/null +++ b/src/Auth/Exception/UserNameOrPasswordError.php @@ -0,0 +1,16 @@ +password = password_hash($password, PASSWORD_DEFAULT); + } + + public function verifyPassword($password){ + return password_verify($password, $this->password); + } +} \ No newline at end of file diff --git a/src/Common/Controller/ExtendController.php b/src/Common/Controller/ExtendController.php new file mode 100644 index 0000000..478ecc4 --- /dev/null +++ b/src/Common/Controller/ExtendController.php @@ -0,0 +1,64 @@ +request->getPost($field, $filterType, $defaultValue); + if(!empty($value)){ + return $value; + } + $value = $this->request->getJsonRawBody(true); + if(empty($value)){ + return []; + } + if(empty($field)){ + return $value; + } + return isset($value[$field]) ? (new Filter())->sanitize($value[$field], $filterType) : $defaultValue; + } + + public function responseOk($data=[], $code = 200, $httpCode = 200,$status = 'ok'){ + return $this->response + ->setStatusCode($httpCode) + ->setHeader('Access-Control-Allow-Origin','*') + ->setJsonContent([ + 'ok'=>1, + 'status'=>$status, + 'code'=>$code, + 'data'=>$data + ]); + } + + public function responseError($message = null, $code = 500, $httpCode = 200,$status = 'error'){ + if(is_array($message)){ + $message = $message[0]; + } + if($message instanceof Message){ + $message = $message->getMessage(); + } + return $this->response + ->setStatusCode($httpCode) + ->setJsonContent([ + 'ok'=>0, + 'status'=>$status, + 'code'=>$code, + 'message'=>$message + ]); + } +} \ No newline at end of file diff --git a/src/Common/Exception/FilterFormatError.php b/src/Common/Exception/FilterFormatError.php new file mode 100644 index 0000000..3ce70f3 --- /dev/null +++ b/src/Common/Exception/FilterFormatError.php @@ -0,0 +1,15 @@ +$value){ + if(substr($key, 0, 1) != '$'){ + $fragments[] = self::filterSegmentToParameters($value, $key); + }else{ + switch (strtoupper($key)){ + case '$AND':case '$OR': + $fragments[] = self::filterSegmentToParameters($value, $key); + break; + case '$GT':case '$GTE':case '$LT':case '$LTE':case '$IN':case '$NIN':case '$EQ':case 'NE': + $fragments[] = self::filterExpressionToParameter($upKey, $key, $value); + break; + case '$NOT': + $fragments[] = sprintf('NOT (%s)', self::filterSegmentToParameters($value, '$AND')); + break; + default: + throw new FilterFormatError(); + } + } + } + foreach($fragments as &$value){ + $value = sprintf('(%s)', $value); + } + return implode(' '.substr($upKey, 1).' ', $fragments); + }else{ + return self::filterExpressionToParameter($upKey, '$EQ', $filter); + } + } + + static private $valueOps = [ + '$GT'=>'>', + '$GTE'=>'>=', + '$LT'=>'<', + '$LTE'=>'<=', + '$NEQ'=>'<>', + '$EQ'=>'=', + '$IN'=>'IN', + '$NIN'=>'NOT IN', + ]; + + /** + * @param $upKey + * @param $opKey + * @param $value + * @return string + * @throws FilterFormatError + */ + static private function filterExpressionToParameter($upKey, $opKey, $value){ + if(!isset(self::$valueOps[$opKey])){ + throw new FilterFormatError(); + } + $valueOp = self::$valueOps[$opKey]; + if(is_array($value)){ + $valueArray = []; + foreach($value as $v){ + $valueArray[] = self::escapeToParam($v); + } + return sprintf("%s %s (%s)", self::escape($upKey), $valueOp, implode(', ', $valueArray)); + }else{ + return sprintf("%s %s %s", self::escape($upKey), $valueOp, self::escapeToParam($value)); + } + } + + /** + * @param $value + * @return string + * @throws FilterFormatError + */ + static private function escapeToParam($value){ + if(is_numeric($value)){ + return strval($value); + }else if(is_string($value)) { + return sprintf("'%s'", self::escape($value)); + }else{ + throw new FilterFormatError(); + } + } + + static public function escape($string){ + return sqlite_escape_string($string); + } +} \ No newline at end of file