diff --git a/README.en-US.md b/README.en-US.md
index b5cfd4e8..dcb90ebb 100644
--- a/README.en-US.md
+++ b/README.en-US.md
@@ -6,7 +6,7 @@
-
+
@@ -14,9 +14,6 @@
-
-
-
@@ -59,7 +56,7 @@ These artifacts are available from Maven Central:
me.zhyd.oauth
JustAuth
- 1.16.1
+ 1.16.2
```
- Using JustAuth
diff --git a/README.md b/README.md
index fad9cb34..5c86ac4a 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
-
+
@@ -14,9 +14,6 @@
-
-
-
@@ -69,7 +66,7 @@ JustAuth 集成了诸如:Github、Gitee、支付宝、新浪微博、微信、
me.zhyd.oauth
JustAuth
- 1.16.1
+ 1.16.2
```
- 调用api
diff --git a/bin/version.txt b/bin/version.txt
index 41c11ffb..4a02d2c3 100644
--- a/bin/version.txt
+++ b/bin/version.txt
@@ -1 +1 @@
-1.16.1
+1.16.2
diff --git a/pom.xml b/pom.xml
index 0e8f7966..f3ec0d25 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
me.zhyd.oauth
JustAuth
- 1.16.1
+ 1.16.2
JustAuth
https://gitee.com/yadong.zhang/JustAuth
diff --git a/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java b/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java
index 2e0f67fb..c471da7e 100644
--- a/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java
+++ b/src/main/java/me/zhyd/oauth/config/AuthDefaultSource.java
@@ -976,4 +976,25 @@ public String revoke() {
return "https://%s.okta.com/oauth2/%s/v1/revoke";
}
},
+ /**
+ * 程序员客栈
+ *
+ * @since 1.16.2
+ */
+ PROGINN {
+ @Override
+ public String authorize() {
+ return "https://www.proginn.com/oauth2/authorize";
+ }
+
+ @Override
+ public String accessToken() {
+ return "https://www.proginn.com/oauth2/access_token";
+ }
+
+ @Override
+ public String userInfo() {
+ return "https://www.proginn.com/openapi/user/basic_info";
+ }
+ },
}
diff --git a/src/main/java/me/zhyd/oauth/enums/scope/AuthProginnScope.java b/src/main/java/me/zhyd/oauth/enums/scope/AuthProginnScope.java
new file mode 100644
index 00000000..3ffe4170
--- /dev/null
+++ b/src/main/java/me/zhyd/oauth/enums/scope/AuthProginnScope.java
@@ -0,0 +1,33 @@
+package me.zhyd.oauth.enums.scope;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * Gitee 平台 OAuth 授权范围
+ *
+ * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
+ * @version 1.0.0
+ * @since 1.0.0
+ */
+@Getter
+@AllArgsConstructor
+public enum AuthProginnScope implements AuthScope {
+
+ /**
+ * {@code scope} 含义,以{@code description} 为准
+ */
+ BASIC("basic", "访问用户的基本信息", true),
+ /**
+ * 以上 scope 需要单独向程序员客栈平台申请,否则不可使用
+ */
+ email("email", "获取用户的邮箱", false),
+ realname("realname", "获取用户的真实姓名", false),
+ cellphone("cellphone", "获取用户的手机号码", false),
+ ;
+
+ private final String scope;
+ private final String description;
+ private final boolean isDefault;
+
+}
diff --git a/src/main/java/me/zhyd/oauth/request/AuthProginnRequest.java b/src/main/java/me/zhyd/oauth/request/AuthProginnRequest.java
new file mode 100644
index 00000000..1fcd0aca
--- /dev/null
+++ b/src/main/java/me/zhyd/oauth/request/AuthProginnRequest.java
@@ -0,0 +1,97 @@
+package me.zhyd.oauth.request;
+
+import com.alibaba.fastjson.JSONObject;
+import me.zhyd.oauth.cache.AuthStateCache;
+import me.zhyd.oauth.config.AuthConfig;
+import me.zhyd.oauth.config.AuthDefaultSource;
+import me.zhyd.oauth.enums.AuthUserGender;
+import me.zhyd.oauth.enums.scope.AuthProginnScope;
+import me.zhyd.oauth.exception.AuthException;
+import me.zhyd.oauth.model.AuthCallback;
+import me.zhyd.oauth.model.AuthToken;
+import me.zhyd.oauth.model.AuthUser;
+import me.zhyd.oauth.utils.AuthScopeUtils;
+import me.zhyd.oauth.utils.HttpUtils;
+import me.zhyd.oauth.utils.UrlBuilder;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 程序员客栈
+ *
+ * @author yadong.zhang (yadong.zhang0415(a)gmail.com)
+ * @since 1.16.2
+ */
+public class AuthProginnRequest extends AuthDefaultRequest {
+
+ public AuthProginnRequest(AuthConfig config) {
+ super(config, AuthDefaultSource.PROGINN);
+ }
+
+ public AuthProginnRequest(AuthConfig config, AuthStateCache authStateCache) {
+ super(config, AuthDefaultSource.PROGINN, authStateCache);
+ }
+
+ @Override
+ protected AuthToken getAccessToken(AuthCallback authCallback) {
+ Map params = new HashMap<>();
+ params.put("code", authCallback.getCode());
+ params.put("client_id", config.getClientId());
+ params.put("client_secret", config.getClientSecret());
+ params.put("grant_type", "authorization_code");
+ params.put("redirect_uri", config.getRedirectUri());
+ String response = new HttpUtils(config.getHttpConfig()).post(AuthDefaultSource.PROGINN.accessToken(), params, false);
+ JSONObject accessTokenObject = JSONObject.parseObject(response);
+ this.checkResponse(accessTokenObject);
+ return AuthToken.builder()
+ .accessToken(accessTokenObject.getString("access_token"))
+ .refreshToken(accessTokenObject.getString("refresh_token"))
+ .uid(accessTokenObject.getString("uid"))
+ .tokenType(accessTokenObject.getString("token_type"))
+ .expireIn(accessTokenObject.getIntValue("expires_in"))
+ .build();
+ }
+
+ @Override
+ protected AuthUser getUserInfo(AuthToken authToken) {
+ String userInfo = doGetUserInfo(authToken);
+ JSONObject object = JSONObject.parseObject(userInfo);
+ this.checkResponse(object);
+ return AuthUser.builder()
+ .rawUserInfo(object)
+ .uuid(object.getString("uid"))
+ .username(object.getString("nickname"))
+ .nickname(object.getString("nickname"))
+ .avatar(object.getString("avatar"))
+ .email(object.getString("email"))
+ .gender(AuthUserGender.UNKNOWN)
+ .token(authToken)
+ .source(source.toString())
+ .build();
+ }
+
+ /**
+ * 检查响应内容是否正确
+ *
+ * @param object 请求响应内容
+ */
+ private void checkResponse(JSONObject object) {
+ if (object.containsKey("error")) {
+ throw new AuthException(object.getString("error_description"));
+ }
+ }
+
+ /**
+ * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state}
+ *
+ * @param state state 验证授权流程的参数,可以防止csrf
+ * @return 返回授权地址
+ */
+ @Override
+ public String authorize(String state) {
+ return UrlBuilder.fromBaseUrl(super.authorize(state))
+ .queryParam("scope", this.getScopes(" ", true, AuthScopeUtils.getDefaultScopes(AuthProginnScope.values())))
+ .build();
+ }
+}