fix: improve code specification (#231)

This commit is contained in:
sh1luo
2021-08-07 22:02:56 +08:00
committed by Yang Luo
parent a271ef0719
commit 8c66ef6860
36 changed files with 209 additions and 164 deletions

175
README.md
View File

@@ -1,146 +1,131 @@
Casdoor Casdoor
==== ====
[![Go Report Card](https://goreportcard.com/badge/github.com/casbin/casdoor)](https://goreportcard.com/report/github.com/casbin/casdoor) <img src="https://img.shields.io/github/license/casbin/casdoor?style=flat-square" alt="license"> [![GitHub issues](https://img.shields.io/github/issues/casbin/casdoor?style=flat-square)](https://github.com/casbin/casdoor/issues) [![GitHub stars](https://img.shields.io/github/stars/casbin/casdoor?style=flat-square)](https://github.com/casbin/casdoor/stargazers) [![GitHub forks](https://img.shields.io/github/forks/casbin/casdoor?style=flat-square)](https://github.com/casbin/casdoor/network)
Casdoor is a UI-first centralized authentication / Single-Sign-On (SSO) platform based on OAuth 2.0 / OIDC. Casdoor is a UI-first centralized authentication / Single-Sign-On (SSO) platform based on OAuth 2.0 / OIDC.
## Online demo ## Online demo
### Casdoor Deployed site: https://door.casbin.com/
Casdoor is the authentication server. It serves both the web UI and the login requests from the application users. ## Quick Start
- Deployed site: https://door.casbin.com/ Run your own casdoor program in a few minutes:smiley:
- Source code: https://github.com/casbin/casdoor (this repo)
Global admin login: ### Download
- Username: `admin` There are two methods, get code via go subcommand `get`:
- Password: `123`
### Web application ```shell
go get github.com/casbin/casdoor
```
Casbin-OA is one of our applications that use Casdoor as authentication. or `git`:
- Deployed site: https://oa.casbin.com/ ```bash
- Source code: https://github.com/casbin/casbin-oa git clone https://github.com/casbin/casdoor
```
## Architecture Finally, change directory:
Casdoor contains 2 parts: ```bash
cd casdoor/
```
Name | Description | Language | Source code We provide two start up methods for all kinds of users.
----|------|----|----
Frontend | Web frontend UI for Casdoor | Javascript + React | https://github.com/casbin/casdoor/tree/master/web
Backend | RESTful API backend for Casdoor | Golang + Beego + MySQL | https://github.com/casbin/casdoor
## Installation ### Manual
- Get code via `go get`: #### Simple configuration
```shell Edit `conf/app.conf`, modify `dataSourceName` to correct database info, which follows this format:
go get github.com/casbin/casdoor
```
or `git clone`: ```bash
username:password@tcp(database_ip:database_port)/
```
```shell #### Run
git clone https://github.com/casbin/casdoor
```
## Run through Docker Casdoor provides two run modes, the difference is binary size and user prompt.
- Install Docker and Docker-compose,you see [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/)
- vi casdoor/conf/app.conf
- Modify dataSourceName = root:123@tcp(localhost:3306)/ to dataSourceName = root:123@tcp(db:3306)/
- Execute the following command
```shell
docker-compose up
```
- Open browser:
http://localhost:8000/ ##### Dev Mode
## Run (Dev Environment) Edit `conf/app.conf`, set `runmode=dev`. Firstly build front-end files:
- Run backend (in port 8000): ```bash
cd web/ && npm install && npm run start
```
```shell Then build back-end binary file, change directory to root(Relative to casdoor):
go run main.go
```
- Run frontend (in the same machine's port 7001): ```bash
go run main.go
```
```shell That's it! Try to visit http://127.0.0.1:7001/. :small_airplane:
cd web
## npm
npm install
npm run start
## yarn
yarn install
yarn run start
```
- Open browser: ##### Prod Mode
http://localhost:7001/ Edit `conf/app.conf`, set `runmode=prod`. Firstly build front-end files:
## Run (Production Environment) ```bash
cd web/ && npm install && npm run build
```
- build static pages: Then build back-end binary file, change directory to root(Relative to casdoor):
``` ```bash
cd web go build main.go && sudo ./main
## npm ```
npm run build
## yarn
yarn run build
## back to casdoor directory
cd ..
```
- build and run go code: > Notice, you should visit back-end port, default 8000. Now try to visit http://127.0.0.1:8000/
``` ### Docker
go build
./casdoor
```
Now, Casdoor is running on port 8000. You can access Casdoor pages directly in your browser, or you can setup a reverse proxy to hold your domain name, SSL, etc. This method requires [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/) to be installed first.
## Config #### Simple configuration
- Setup database (MySQL): Edit `conf/app.conf`, modify `dataSourceName` to the fixed content:
Casdoor will store its users, nodes and topics informations in a MySQL database named: `casdoor`, will create it if not existed. The DB connection string can be specified at: https://github.com/casbin/casdoor/blob/master/conf/app.conf ```bash
dataSourceName = root:123@tcp(db:3306)/
```
```ini > If you need to modify `conf/app.conf`, you need to re-run `docker-compose up`.
db = mysql
dataSourceName = root:123@tcp(localhost:3306)/
dbName = casdoor
```
- Setup database (Postgres): #### Run
Since we must choose a database when opening Postgres with xorm, you should prepare a database manually before running Casdoor. Let's assume that you have already prepared a database called `casdoor`, then you should specify `app.conf` like this: Just execute:
``` ini ```bash
db = postgres docker-compose up
dataSourceName = "user=postgres password=xxx sslmode=disable dbname=" ```
dbName = casdoor
```
**Please notice:** You can add Postgres parameters in `dataSourceName`, but please make sure that `dataSourceName` ends with `dbname=`. Or database adapter may crash when you launch Casdoor. That's
Casdoor uses XORM to connect to DB, so all DBs supported by XORM can also be used. ## Detailed documentation
- Github corner We also provide a complete [document](https://casdoor.org/) as a reference.
We added a Github icon in the upper right corner, linking to your Github repository address. ## Other examples
You could set `ShowGithubCorner` to hidden it.
Configuration (`web/src/commo/Conf.js`): These all use casdoor as a centralized authentication platform.
```javascript - [Casnode](https://github.com/casbin/casnode): Next-generation forum software based on React + Golang.
export const ShowGithubCorner = true - [Casbin-OA](https://github.com/casbin/casbin-oa): A full-featured OA(Office Assistant) system.
- ......
## Contribute
For casdoor, if you have any questions, you can give Issues, and you can also directly Pull Requests(but we recommend give issues first to communicate with the community).
In addition to contributing codes to casdoor, uou can also contribute to the [internationalization of casdoor](https://crowdin.com/project/casdoor-web) by translating for casdoor in the language you are good at.
Both are welcome! :kissing_smiling_eyes:
## License
[Apache-2.0](https://github.com/casbin/casdoor/blob/master/LICENSE)
export const GithubRepo = "https://github.com/casbin/casdoor" //your github repository
```

View File

@@ -72,6 +72,7 @@ type HumanCheck struct {
CaptchaImage interface{} `json:"captchaImage"` CaptchaImage interface{} `json:"captchaImage"`
} }
// Signup
// @Title Signup // @Title Signup
// @Description sign up a new user // @Description sign up a new user
// @Param username formData string true "The username to sign up" // @Param username formData string true "The username to sign up"
@@ -178,6 +179,7 @@ func (c *ApiController) Signup() {
c.ServeJSON() c.ServeJSON()
} }
// Logout
// @Title Logout // @Title Logout
// @Description logout the current user // @Description logout the current user
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
@@ -197,6 +199,7 @@ func (c *ApiController) Logout() {
c.ServeJSON() c.ServeJSON()
} }
// GetAccount
// @Title GetAccount // @Title GetAccount
// @Description get the details of the current account // @Description get the details of the current account
// @Success 200 {object} controllers.Response The Response object // @Success 200 {object} controllers.Response The Response object
@@ -224,6 +227,7 @@ func (c *ApiController) GetAccount() {
c.ServeJSON() c.ServeJSON()
} }
// UploadAvatar
// @Title UploadAvatar // @Title UploadAvatar
// @Description upload avatar // @Description upload avatar
// @Param avatarfile formData string true "The base64 encode of avatarfile" // @Param avatarfile formData string true "The base64 encode of avatarfile"
@@ -272,6 +276,7 @@ func (c *ApiController) UploadAvatar() {
c.ServeJSON() c.ServeJSON()
} }
// GetHumanCheck ...
func (c *ApiController) GetHumanCheck() { func (c *ApiController) GetHumanCheck() {
c.Data["json"] = HumanCheck{Type: "none"} c.Data["json"] = HumanCheck{Type: "none"}

View File

@@ -20,6 +20,7 @@ import (
"github.com/casbin/casdoor/object" "github.com/casbin/casdoor/object"
) )
// GetApplications
// @Title GetApplications // @Title GetApplications
// @Description get all applications // @Description get all applications
// @Param owner query string true "The owner of applications." // @Param owner query string true "The owner of applications."
@@ -32,6 +33,7 @@ func (c *ApiController) GetApplications() {
c.ServeJSON() c.ServeJSON()
} }
// GetApplication
// @Title GetApplication // @Title GetApplication
// @Description get the detail of an application // @Description get the detail of an application
// @Param id query string true "The id of the application." // @Param id query string true "The id of the application."
@@ -44,6 +46,7 @@ func (c *ApiController) GetApplication() {
c.ServeJSON() c.ServeJSON()
} }
// GetUserApplication
// @Title GetUserApplication // @Title GetUserApplication
// @Description get the detail of the user's application // @Description get the detail of the user's application
// @Param id query string true "The id of the user" // @Param id query string true "The id of the user"
@@ -61,6 +64,7 @@ func (c *ApiController) GetUserApplication() {
c.ServeJSON() c.ServeJSON()
} }
// UpdateApplication
// @Title UpdateApplication // @Title UpdateApplication
// @Description update an application // @Description update an application
// @Param id query string true "The id of the application" // @Param id query string true "The id of the application"
@@ -80,6 +84,7 @@ func (c *ApiController) UpdateApplication() {
c.ServeJSON() c.ServeJSON()
} }
// AddApplication
// @Title AddApplication // @Title AddApplication
// @Description add an application // @Description add an application
// @Param body body object.Application true "The details of the application" // @Param body body object.Application true "The details of the application"
@@ -96,6 +101,7 @@ func (c *ApiController) AddApplication() {
c.ServeJSON() c.ServeJSON()
} }
// DeleteApplication
// @Title DeleteApplication // @Title DeleteApplication
// @Description delete an application // @Description delete an application
// @Param body body object.Application true "The details of the application" // @Param body body object.Application true "The details of the application"

View File

@@ -30,14 +30,14 @@ import (
func codeToResponse(code *object.Code) *Response { func codeToResponse(code *object.Code) *Response {
if code.Code == "" { if code.Code == "" {
return &Response{Status: "error", Msg: code.Message, Data: code.Code} return &Response{Status: "error", Msg: code.Message, Data: code.Code}
} else {
return &Response{Status: "ok", Msg: "", Data: code.Code}
} }
return &Response{Status: "ok", Msg: "", Data: code.Code}
} }
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *RequestForm) *Response { // HandleLoggedIn ...
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *RequestForm) (resp *Response) {
userId := user.GetId() userId := user.GetId()
resp := &Response{}
if form.Type == ResponseTypeLogin { if form.Type == ResponseTypeLogin {
c.SetSessionUsername(userId) c.SetSessionUsername(userId)
util.LogInfo(c.Ctx, "API: [%s] signed in", userId) util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
@@ -72,6 +72,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
return resp return resp
} }
// GetApplicationLogin ...
// @Title GetApplicationLogin // @Title GetApplicationLogin
// @Description get application login // @Description get application login
// @Param clientId query string true "client id" // @Param clientId query string true "client id"
@@ -108,6 +109,7 @@ func setHttpClient(idProvider idp.IdProvider, providerType string) {
} }
} }
// Login ...
// @Title Login // @Title Login
// @Description login // @Description login
// @Param oAuthParams query string true "oAuth parameters" // @Param oAuthParams query string true "oAuth parameters"
@@ -182,13 +184,11 @@ func (c *ApiController) Login() {
c.ResponseError("wrong email!") c.ResponseError("wrong email!")
} }
object.DisableVerificationCode(form.Email) object.DisableVerificationCode(form.Email)
break
case "phone": case "phone":
if user.Phone != form.Email { if user.Phone != form.Email {
c.ResponseError("wrong phone!") c.ResponseError("wrong phone!")
} }
object.DisableVerificationCode(form.Email) object.DisableVerificationCode(form.Email)
break
} }
} else { } else {
password := form.Password password := form.Password
@@ -282,7 +282,7 @@ func (c *ApiController) Login() {
record.Organization = application.Organization record.Organization = application.Organization
record.Username = user.Name record.Username = user.Name
object.AddRecord(record) object.AddRecord(record)
} else { } else {
// Sign up via OAuth // Sign up via OAuth
if !application.EnableSignUp { if !application.EnableSignUp {

View File

@@ -29,6 +29,7 @@ type SessionData struct {
ExpireTime int64 ExpireTime int64
} }
// GetSessionUsername ...
func (c *ApiController) GetSessionUsername() string { func (c *ApiController) GetSessionUsername() string {
// check if user session expired // check if user session expired
sessionData := c.GetSessionData() sessionData := c.GetSessionData()
@@ -48,10 +49,12 @@ func (c *ApiController) GetSessionUsername() string {
return user.(string) return user.(string)
} }
// SetSessionUsername ...
func (c *ApiController) SetSessionUsername(user string) { func (c *ApiController) SetSessionUsername(user string) {
c.SetSession("username", user) c.SetSession("username", user)
} }
// GetSessionData ...
func (c *ApiController) GetSessionData() *SessionData { func (c *ApiController) GetSessionData() *SessionData {
session := c.GetSession("SessionData") session := c.GetSession("SessionData")
if session == nil { if session == nil {
@@ -67,6 +70,7 @@ func (c *ApiController) GetSessionData() *SessionData {
return sessionData return sessionData
} }
// SetSessionData ...
func (c *ApiController) SetSessionData(s *SessionData) { func (c *ApiController) SetSessionData(s *SessionData) {
if s == nil { if s == nil {
c.DelSession("SessionData") c.DelSession("SessionData")

View File

@@ -97,7 +97,6 @@ func (c *ApiController) GetLdapUser() {
c.Data["json"] = Response{Status: "ok", Data: resp} c.Data["json"] = Response{Status: "ok", Data: resp}
c.ServeJSON() c.ServeJSON()
return
} }
func (c *ApiController) GetLdaps() { func (c *ApiController) GetLdaps() {

View File

@@ -24,6 +24,7 @@ type LinkForm struct {
ProviderType string `json:"providerType"` ProviderType string `json:"providerType"`
} }
// Unlink ...
func (c *ApiController) Unlink() { func (c *ApiController) Unlink() {
userId, ok := c.RequireSignedIn() userId, ok := c.RequireSignedIn()
if !ok { if !ok {

View File

@@ -20,6 +20,7 @@ import (
"github.com/casbin/casdoor/object" "github.com/casbin/casdoor/object"
) )
// GetOrganizations ...
// @Title GetOrganizations // @Title GetOrganizations
// @Description get organizations // @Description get organizations
// @Param owner query string true "owner" // @Param owner query string true "owner"
@@ -32,6 +33,7 @@ func (c *ApiController) GetOrganizations() {
c.ServeJSON() c.ServeJSON()
} }
// GetOrganization ...
// @Title GetOrganization // @Title GetOrganization
// @Description get organization // @Description get organization
// @Param id query string true "organization id" // @Param id query string true "organization id"
@@ -44,6 +46,7 @@ func (c *ApiController) GetOrganization() {
c.ServeJSON() c.ServeJSON()
} }
// UpdateOrganization ...
// @Title UpdateOrganization // @Title UpdateOrganization
// @Description update organization // @Description update organization
// @Param id query string true "The id of the organization" // @Param id query string true "The id of the organization"
@@ -63,6 +66,7 @@ func (c *ApiController) UpdateOrganization() {
c.ServeJSON() c.ServeJSON()
} }
// AddOrganization ...
// @Title AddOrganization // @Title AddOrganization
// @Description add organization // @Description add organization
// @Param body body object.Organization true "The details of the organization" // @Param body body object.Organization true "The details of the organization"
@@ -79,6 +83,7 @@ func (c *ApiController) AddOrganization() {
c.ServeJSON() c.ServeJSON()
} }
// DeleteOrganization ...
// @Title DeleteOrganization // @Title DeleteOrganization
// @Description delete organization // @Description delete organization
// @Param body body object.Organization true "The details of the organization" // @Param body body object.Organization true "The details of the organization"

View File

@@ -20,6 +20,7 @@ import (
"github.com/casbin/casdoor/object" "github.com/casbin/casdoor/object"
) )
// GetProviders
// @Title GetProviders // @Title GetProviders
// @Description get providers // @Description get providers
// @Param owner query string true "The owner of providers" // @Param owner query string true "The owner of providers"

View File

@@ -20,6 +20,7 @@ import (
"github.com/casbin/casdoor/object" "github.com/casbin/casdoor/object"
) )
// GetRecords
// @Title GetRecords // @Title GetRecords
// @Description get all records // @Description get all records
// @Success 200 {array} object.Records The Response object // @Success 200 {array} object.Records The Response object
@@ -29,6 +30,7 @@ func (c *ApiController) GetRecords() {
c.ServeJSON() c.ServeJSON()
} }
// GetRecordsByFilter
// @Title GetRecordsByFilter // @Title GetRecordsByFilter
// @Description get records by filter // @Description get records by filter
// @Param body body object.Records true "filter Record message" // @Param body body object.Records true "filter Record message"

View File

@@ -25,6 +25,7 @@ import (
sender "github.com/casdoor/go-sms-sender" sender "github.com/casdoor/go-sms-sender"
) )
// SendEmail
// @Title SendEmail // @Title SendEmail
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs. // @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
// @Param clientId query string true "The clientId of the application" // @Param clientId query string true "The clientId of the application"
@@ -84,8 +85,7 @@ func (c *ApiController) SendEmail() {
emailForm.Title, emailForm.Title,
emailForm.Content, emailForm.Content,
receiver, receiver,
emailForm.Sender); emailForm.Sender); len(msg) == 0 {
len(msg) == 0 {
ok++ ok++
} }
} }
@@ -94,6 +94,7 @@ func (c *ApiController) SendEmail() {
c.ServeJSON() c.ServeJSON()
} }
// SendSms
// @Title SendSms // @Title SendSms
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs. // @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
// @Param clientId query string true "The clientId of the application" // @Param clientId query string true "The clientId of the application"
@@ -148,7 +149,7 @@ func (c *ApiController) SendSms() {
} }
} }
if len(invalidReceivers) != 0{ if len(invalidReceivers) != 0 {
c.ResponseError("Invalid phone numbers", invalidReceivers) c.ResponseError("Invalid phone numbers", invalidReceivers)
return return
} }

View File

@@ -20,6 +20,7 @@ import (
"github.com/casbin/casdoor/object" "github.com/casbin/casdoor/object"
) )
// GetTokens
// @Title GetTokens // @Title GetTokens
// @Description get tokens // @Description get tokens
// @Param owner query string true "The owner of tokens" // @Param owner query string true "The owner of tokens"
@@ -32,6 +33,7 @@ func (c *ApiController) GetTokens() {
c.ServeJSON() c.ServeJSON()
} }
// GetToken
// @Title GetToken // @Title GetToken
// @Description get token // @Description get token
// @Param id query string true "The id of token" // @Param id query string true "The id of token"
@@ -44,6 +46,7 @@ func (c *ApiController) GetToken() {
c.ServeJSON() c.ServeJSON()
} }
// UpdateToken
// @Title UpdateToken // @Title UpdateToken
// @Description update token // @Description update token
// @Param id query string true "The id of token" // @Param id query string true "The id of token"
@@ -63,6 +66,7 @@ func (c *ApiController) UpdateToken() {
c.ServeJSON() c.ServeJSON()
} }
// AddToken
// @Title AddToken // @Title AddToken
// @Description add token // @Description add token
// @Param body body object.Token true "Details of the token" // @Param body body object.Token true "Details of the token"
@@ -79,6 +83,7 @@ func (c *ApiController) AddToken() {
c.ServeJSON() c.ServeJSON()
} }
// DeleteToken
// @Title DeleteToken // @Title DeleteToken
// @Description delete token // @Description delete token
// @Param body body object.Token true "Details of the token" // @Param body body object.Token true "Details of the token"
@@ -95,6 +100,7 @@ func (c *ApiController) DeleteToken() {
c.ServeJSON() c.ServeJSON()
} }
// GetOAuthToken
// @Title GetOAuthToken // @Title GetOAuthToken
// @Description get oAuth token // @Description get oAuth token
// @Param grant_type query string true "oAuth grant type" // @Param grant_type query string true "oAuth grant type"

View File

@@ -23,6 +23,7 @@ import (
"github.com/casbin/casdoor/original" "github.com/casbin/casdoor/original"
) )
// GetGlobalUsers
// @Title GetGlobalUsers // @Title GetGlobalUsers
// @Description get global users // @Description get global users
// @Success 200 {array} object.User The Response object // @Success 200 {array} object.User The Response object
@@ -32,6 +33,7 @@ func (c *ApiController) GetGlobalUsers() {
c.ServeJSON() c.ServeJSON()
} }
// GetUsers
// @Title GetUsers // @Title GetUsers
// @Description // @Description
// @Param owner query string true "The owner of users" // @Param owner query string true "The owner of users"
@@ -44,6 +46,7 @@ func (c *ApiController) GetUsers() {
c.ServeJSON() c.ServeJSON()
} }
// GetUser
// @Title GetUser // @Title GetUser
// @Description get user // @Description get user
// @Param id query string true "The id of the user" // @Param id query string true "The id of the user"
@@ -56,6 +59,7 @@ func (c *ApiController) GetUser() {
c.ServeJSON() c.ServeJSON()
} }
// UpdateUser
// @Title UpdateUser // @Title UpdateUser
// @Description update user // @Description update user
// @Param id query string true "The id of the user" // @Param id query string true "The id of the user"
@@ -86,6 +90,7 @@ func (c *ApiController) UpdateUser() {
c.ServeJSON() c.ServeJSON()
} }
// AddUser
// @Title AddUser // @Title AddUser
// @Description add user // @Description add user
// @Param body body object.User true "The details of the user" // @Param body body object.User true "The details of the user"
@@ -102,6 +107,7 @@ func (c *ApiController) AddUser() {
c.ServeJSON() c.ServeJSON()
} }
// DeleteUser
// @Title DeleteUser // @Title DeleteUser
// @Description delete user // @Description delete user
// @Param body body object.User true "The details of the user" // @Param body body object.User true "The details of the user"
@@ -118,6 +124,7 @@ func (c *ApiController) DeleteUser() {
c.ServeJSON() c.ServeJSON()
} }
// GetEmailAndPhone
// @Title GetEmailAndPhone // @Title GetEmailAndPhone
// @Description get email and phone by username // @Description get email and phone by username
// @Param username formData string true "The username of the user" // @Param username formData string true "The username of the user"
@@ -156,6 +163,7 @@ func (c *ApiController) GetEmailAndPhone() {
c.ServeJSON() c.ServeJSON()
} }
// SetPassword
// @Title SetPassword // @Title SetPassword
// @Description set password // @Description set password
// @Param userOwner formData string true "The owner of the user" // @Param userOwner formData string true "The owner of the user"
@@ -209,11 +217,9 @@ func (c *ApiController) SetPassword() {
c.ResponseError(msg) c.ResponseError(msg)
return return
} }
} else {
} }
if strings.Index(newPassword, " ") >= 0 { if strings.Contains(newPassword, " ") {
c.ResponseError("New password cannot contain blank space.") c.ResponseError("New password cannot contain blank space.")
return return
} }

View File

@@ -24,6 +24,7 @@ import (
var defaultHttpClient *http.Client var defaultHttpClient *http.Client
var proxyHttpClient *http.Client var proxyHttpClient *http.Client
// InitHttpClient ...
func InitHttpClient() { func InitHttpClient() {
// not use proxy // not use proxy
defaultHttpClient = http.DefaultClient defaultHttpClient = http.DefaultClient
@@ -54,6 +55,7 @@ func InitHttpClient() {
//println("Response status: %s", resp.Status) //println("Response status: %s", resp.Status)
} }
// ResponseError ...
func (c *ApiController) ResponseError(error string, data ...interface{}) { func (c *ApiController) ResponseError(error string, data ...interface{}) {
resp := Response{Status: "error", Msg: error} resp := Response{Status: "error", Msg: error}
switch len(data) { switch len(data) {
@@ -67,11 +69,13 @@ func (c *ApiController) ResponseError(error string, data ...interface{}) {
c.ServeJSON() c.ServeJSON()
} }
// ResponseErrorWithData ...
func (c *ApiController) ResponseErrorWithData(error string, data interface{}) { func (c *ApiController) ResponseErrorWithData(error string, data interface{}) {
c.Data["json"] = Response{Status: "error", Msg: error, Data: data} c.Data["json"] = Response{Status: "error", Msg: error, Data: data}
c.ServeJSON() c.ServeJSON()
} }
// RequireSignedIn ...
func (c *ApiController) RequireSignedIn() (string, bool) { func (c *ApiController) RequireSignedIn() (string, bool) {
userId := c.GetSessionUsername() userId := c.GetSessionUsername()
if userId == "" { if userId == "" {

View File

@@ -33,6 +33,7 @@ func (c *ApiController) getCurrentUser() *object.User {
return user return user
} }
// SendVerificationCode ...
func (c *ApiController) SendVerificationCode() { func (c *ApiController) SendVerificationCode() {
destType := c.Ctx.Request.Form.Get("type") destType := c.Ctx.Request.Form.Get("type")
dest := c.Ctx.Request.Form.Get("dest") dest := c.Ctx.Request.Form.Get("dest")
@@ -42,7 +43,7 @@ func (c *ApiController) SendVerificationCode() {
checkKey := c.Ctx.Request.Form.Get("checkKey") checkKey := c.Ctx.Request.Form.Get("checkKey")
remoteAddr := util.GetIPFromRequest(c.Ctx.Request) remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
if len(destType) == 0 || len(dest) == 0 || len(orgId) == 0 || strings.Index(orgId, "/") < 0 || len(checkType) == 0 || len(checkId) == 0 || len(checkKey) == 0 { if len(destType) == 0 || len(dest) == 0 || len(orgId) == 0 || !strings.Contains(orgId, "/") || len(checkType) == 0 || len(checkId) == 0 || len(checkKey) == 0 {
c.ResponseError("Missing parameter.") c.ResponseError("Missing parameter.")
return return
} }
@@ -97,6 +98,7 @@ func (c *ApiController) SendVerificationCode() {
c.ServeJSON() c.ServeJSON()
} }
// ResetEmailOrPhone ...
func (c *ApiController) ResetEmailOrPhone() { func (c *ApiController) ResetEmailOrPhone() {
userId, ok := c.RequireSignedIn() userId, ok := c.RequireSignedIn()
if !ok { if !ok {

2
go.mod
View File

@@ -23,7 +23,7 @@ require (
github.com/satori/go.uuid v1.2.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/thanhpk/randstr v1.0.4 github.com/thanhpk/randstr v1.0.4
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect

8
go.sum
View File

@@ -386,8 +386,9 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -435,8 +436,11 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44 h1:Bli41pIlzTzf3KEY06n+xnzK/BESIg2ze4Pgfh/aI8c=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View File

@@ -20,7 +20,6 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@@ -48,6 +47,7 @@ type DingTalkIdProvider struct {
Config *oauth2.Config Config *oauth2.Config
} }
// NewDingTalkIdProvider ...
func NewDingTalkIdProvider(clientId string, clientSecret string, redirectUrl string) *DingTalkIdProvider { func NewDingTalkIdProvider(clientId string, clientSecret string, redirectUrl string) *DingTalkIdProvider {
idp := &DingTalkIdProvider{} idp := &DingTalkIdProvider{}
@@ -57,6 +57,7 @@ func NewDingTalkIdProvider(clientId string, clientSecret string, redirectUrl str
return idp return idp
} }
// SetHttpClient ...
func (idp *DingTalkIdProvider) SetHttpClient(client *http.Client) { func (idp *DingTalkIdProvider) SetHttpClient(client *http.Client) {
idp.Client = client idp.Client = client
} }
@@ -136,7 +137,7 @@ func (idp *DingTalkIdProvider) GetToken(code string) (*oauth2.Token, error) {
_ = json.Unmarshal(body, &info) _ = json.Unmarshal(body, &info)
errCode := info.Errcode errCode := info.Errcode
if errCode != 0 { if errCode != 0 {
return nil, errors.New(fmt.Sprintf("%d: %s", errCode, info.Errmsg)) return nil, fmt.Errorf("%d: %s", errCode, info.Errmsg)
} }
u2 := fmt.Sprintf("%s?appkey=%s&appsecret=%s", idp.Config.Endpoint.TokenURL, idp.Config.ClientID, idp.Config.ClientSecret) u2 := fmt.Sprintf("%s?appkey=%s&appsecret=%s", idp.Config.Endpoint.TokenURL, idp.Config.ClientID, idp.Config.ClientSecret)
@@ -151,7 +152,7 @@ func (idp *DingTalkIdProvider) GetToken(code string) (*oauth2.Token, error) {
tokenResp := DingTalkAccessToken{} tokenResp := DingTalkAccessToken{}
_ = json.Unmarshal(body, &tokenResp) _ = json.Unmarshal(body, &tokenResp)
if tokenResp.ErrCode != 0 { if tokenResp.ErrCode != 0 {
return nil, errors.New(fmt.Sprintf("%d: %s", tokenResp.ErrCode, tokenResp.ErrMsg)) return nil, fmt.Errorf("%d: %s", tokenResp.ErrCode, tokenResp.ErrMsg)
} }
// use unionid to get userid // use unionid to get userid
@@ -183,6 +184,7 @@ type UnionIdResponse struct {
RequestId string `json:"request_id"` RequestId string `json:"request_id"`
} }
// GetUseridByUnionid ...
func (idp *DingTalkIdProvider) GetUseridByUnionid(accesstoken, unionid string) (userid string, err error) { func (idp *DingTalkIdProvider) GetUseridByUnionid(accesstoken, unionid string) (userid string, err error) {
u := fmt.Sprintf("https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token=%s&unionid=%s", u := fmt.Sprintf("https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token=%s&unionid=%s",
accesstoken, unionid) accesstoken, unionid)
@@ -195,7 +197,7 @@ func (idp *DingTalkIdProvider) GetUseridByUnionid(accesstoken, unionid string) (
_ = json.Unmarshal([]byte(useridInfo), &uresp) _ = json.Unmarshal([]byte(useridInfo), &uresp)
errcode := uresp.Errcode errcode := uresp.Errcode
if errcode != 0 { if errcode != 0 {
return "", errors.New(fmt.Sprintf("%d: %s", errcode, uresp.Errmsg)) return "", fmt.Errorf("%d: %s", errcode, uresp.Errmsg)
} }
return uresp.Result.Userid, nil return uresp.Result.Userid, nil
} }

View File

@@ -61,7 +61,7 @@ func (idp *GithubIdProvider) getConfig() *oauth2.Config {
} }
func (idp *GithubIdProvider) GetToken(code string) (*oauth2.Token, error) { func (idp *GithubIdProvider) GetToken(code string) (*oauth2.Token, error) {
ctx := context.WithValue(oauth2.NoContext, oauth2.HTTPClient, idp.Client) ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
return idp.Config.Exchange(ctx, code) return idp.Config.Exchange(ctx, code)
} }

View File

@@ -61,7 +61,7 @@ func (idp *GoogleIdProvider) getConfig() *oauth2.Config {
} }
func (idp *GoogleIdProvider) GetToken(code string) (*oauth2.Token, error) { func (idp *GoogleIdProvider) GetToken(code string) (*oauth2.Token, error) {
ctx := context.WithValue(oauth2.NoContext, oauth2.HTTPClient, idp.Client) ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
return idp.Config.Exchange(ctx, code) return idp.Config.Exchange(ctx, code)
} }

View File

@@ -96,9 +96,9 @@ func (idp *LinkedInIdProvider) GetToken(code string) (*oauth2.Token, error) {
} }
token := &oauth2.Token{ token := &oauth2.Token{
AccessToken: tokenResp.AccessToken, AccessToken: tokenResp.AccessToken,
TokenType: "Bearer", TokenType: "Bearer",
Expiry: time.Unix(time.Now().Unix()+tokenResp.ExpiresIn, 0), Expiry: time.Unix(time.Now().Unix()+tokenResp.ExpiresIn, 0),
} }
return token, nil return token, nil
@@ -186,14 +186,14 @@ func (idp *LinkedInIdProvider) GetToken(code string) (*oauth2.Token, error) {
type LinkedInUserInfo struct { type LinkedInUserInfo struct {
FirstName struct { FirstName struct {
Localized map[string]string `json:"localized"` Localized map[string]string `json:"localized"`
PreferredLocale struct { PreferredLocale struct {
Country string `json:"country"` Country string `json:"country"`
Language string `json:"language"` Language string `json:"language"`
} `json:"preferredLocale"` } `json:"preferredLocale"`
} `json:"firstName"` } `json:"firstName"`
LastName struct { LastName struct {
Localized map[string]string `json:"localized"` Localized map[string]string `json:"localized"`
PreferredLocale struct { PreferredLocale struct {
Country string `json:"country"` Country string `json:"country"`
Language string `json:"language"` Language string `json:"language"`
@@ -301,7 +301,7 @@ func (idp *LinkedInIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
userInfo := UserInfo{ userInfo := UserInfo{
Id: linkedInUserInfo.Id, Id: linkedInUserInfo.Id,
DisplayName: username, DisplayName: username,
Username: username, Username: username,
Email: linkedInUserEmail.Elements[0].Handle.EmailAddress, Email: linkedInUserEmail.Elements[0].Handle.EmailAddress,
AvatarUrl: linkedInUserInfo.ProfilePicture.DisplayImage1.Elements[0].Identifiers[0].Identifier, AvatarUrl: linkedInUserInfo.ProfilePicture.DisplayImage1.Elements[0].Identifiers[0].Identifier,
} }

View File

@@ -34,6 +34,7 @@ type IdProvider interface {
GetUserInfo(token *oauth2.Token) (*UserInfo, error) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
} }
// GetIdProvider ...
func GetIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string) IdProvider { func GetIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string) IdProvider {
if providerType == "GitHub" { if providerType == "GitHub" {
return NewGithubIdProvider(clientId, clientSecret, redirectUrl) return NewGithubIdProvider(clientId, clientSecret, redirectUrl)

View File

@@ -173,7 +173,7 @@ func (idp *QqIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
} }
if qqUserInfo.Ret != 0 { if qqUserInfo.Ret != 0 {
return nil, errors.New(fmt.Sprintf("ret expected 0, got %d", qqUserInfo.Ret)) return nil, fmt.Errorf("ret expected 0, got %d", qqUserInfo.Ret)
} }
userInfo := UserInfo{ userInfo := UserInfo{

View File

@@ -99,7 +99,7 @@ func (idp *WeChatIdProvider) GetToken(code string) (*oauth2.Token, error) {
} }
var wechatAccessToken WechatAccessToken var wechatAccessToken WechatAccessToken
if err = json.Unmarshal([]byte(buf.String()), &wechatAccessToken); err != nil { if err = json.Unmarshal(buf.Bytes(), &wechatAccessToken); err != nil {
return nil, err return nil, err
} }
@@ -168,7 +168,7 @@ func (idp *WeChatIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = json.Unmarshal([]byte(buf.String()), &wechatUserInfo); err != nil { if err = json.Unmarshal(buf.Bytes(), &wechatUserInfo); err != nil {
return nil, err return nil, err
} }

View File

@@ -99,7 +99,7 @@ func (a *Adapter) open() {
} }
func (a *Adapter) close() { func (a *Adapter) close() {
a.Engine.Close() _ = a.Engine.Close()
a.Engine = nil a.Engine = nil
} }

View File

@@ -24,7 +24,7 @@ import (
var reWhiteSpace *regexp.Regexp var reWhiteSpace *regexp.Regexp
func init() { func init() {
reWhiteSpace, _ = regexp.Compile("\\s") reWhiteSpace, _ = regexp.Compile(`\s`)
} }
func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, email string, phone string, affiliation string) string { func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, email string, phone string, affiliation string) string {

View File

@@ -152,43 +152,30 @@ func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
switch attribute.Name { switch attribute.Name {
case "uidNumber": case "uidNumber":
ldapUserItem.UidNumber = attribute.Values[0] ldapUserItem.UidNumber = attribute.Values[0]
break
case "uid": case "uid":
ldapUserItem.Uid = attribute.Values[0] ldapUserItem.Uid = attribute.Values[0]
break
case "cn": case "cn":
ldapUserItem.Cn = attribute.Values[0] ldapUserItem.Cn = attribute.Values[0]
break
case "gidNumber": case "gidNumber":
ldapUserItem.GidNumber = attribute.Values[0] ldapUserItem.GidNumber = attribute.Values[0]
break
case "entryUUID": case "entryUUID":
ldapUserItem.Uuid = attribute.Values[0] ldapUserItem.Uuid = attribute.Values[0]
break
case "mail": case "mail":
ldapUserItem.Mail = attribute.Values[0] ldapUserItem.Mail = attribute.Values[0]
break
case "email": case "email":
ldapUserItem.Email = attribute.Values[0] ldapUserItem.Email = attribute.Values[0]
break
case "emailAddress": case "emailAddress":
ldapUserItem.EmailAddress = attribute.Values[0] ldapUserItem.EmailAddress = attribute.Values[0]
break
case "telephoneNumber": case "telephoneNumber":
ldapUserItem.TelephoneNumber = attribute.Values[0] ldapUserItem.TelephoneNumber = attribute.Values[0]
break
case "mobile": case "mobile":
ldapUserItem.Mobile = attribute.Values[0] ldapUserItem.Mobile = attribute.Values[0]
break
case "mobileTelephoneNumber": case "mobileTelephoneNumber":
ldapUserItem.MobileTelephoneNumber = attribute.Values[0] ldapUserItem.MobileTelephoneNumber = attribute.Values[0]
break
case "registeredAddress": case "registeredAddress":
ldapUserItem.RegisteredAddress = attribute.Values[0] ldapUserItem.RegisteredAddress = attribute.Values[0]
break
case "postalAddress": case "postalAddress":
ldapUserItem.PostalAddress = attribute.Values[0] ldapUserItem.PostalAddress = attribute.Values[0]
break
} }
} }
ldapUsers = append(ldapUsers, ldapUserItem) ldapUsers = append(ldapUsers, ldapUserItem)
@@ -348,7 +335,7 @@ func CheckLdapUuidExist(owner string, uuids []string) []string {
// } // }
//} //}
err := adapter.Engine.Where(fmt.Sprintf("ldap IN (%s) AND owner = ?", "'" + strings.Join(uuids, "','") + "'"), owner).Find(&results) err := adapter.Engine.Where(fmt.Sprintf("ldap IN (%s) AND owner = ?", "'"+strings.Join(uuids, "','")+"'"), owner).Find(&results)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@@ -43,8 +43,8 @@ type Provider struct {
AppId string `xorm:"varchar(100)" json:"appId"` AppId string `xorm:"varchar(100)" json:"appId"`
Endpoint string `xorm:"varchar(100)" json:"endpoint"` Endpoint string `xorm:"varchar(100)" json:"endpoint"`
Domain string `xorm:"varchar(100)" json:"domain"` Domain string `xorm:"varchar(100)" json:"domain"`
Bucket string `xorm:"varchar(100)" json:"bucket"` Bucket string `xorm:"varchar(100)" json:"bucket"`
ProviderUrl string `xorm:"varchar(200)" json:"providerUrl"` ProviderUrl string `xorm:"varchar(200)" json:"providerUrl"`
} }

View File

@@ -19,8 +19,8 @@ import (
) )
type Records struct { type Records struct {
Id int `xorm:"int notnull pk autoincr" json:"id"` Id int `xorm:"int notnull pk autoincr" json:"id"`
Record util.Record `xorm:"extends"` Record util.Record `xorm:"extends"`
} }
func AddRecord(record *util.Record) bool { func AddRecord(record *util.Record) bool {

View File

@@ -132,9 +132,9 @@ func GetLastUser(owner string) *User {
if existed { if existed {
return &user return &user
} else {
return nil
} }
return nil
} }
func UpdateUser(id string, user *User) bool { func UpdateUser(id string, user *User) bool {

View File

@@ -16,6 +16,7 @@ package object
import ( import (
"fmt" "fmt"
"reflect"
"testing" "testing"
"github.com/casbin/casdoor/util" "github.com/casbin/casdoor/util"
@@ -78,3 +79,27 @@ func TestGetSaltedPassword(t *testing.T) {
salt := "123" salt := "123"
fmt.Printf("%s -> %s\n", password, getSaltedPassword(password, salt)) fmt.Printf("%s -> %s\n", password, getSaltedPassword(password, salt))
} }
func TestGetMaskedUsers(t *testing.T) {
type args struct {
users []*User
}
tests := []struct {
name string
args args
want []*User
}{
{
name: "1",
args: args{users: []*User{{Password: "casdoor"},{Password: "casbin"}}},
want: []*User{{Password: "***"},{Password: "***"}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetMaskedUsers(tt.args.users); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetMaskedUsers() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -50,15 +50,15 @@ func getUserByClientIdSecret(ctx *context.Context) string {
if app == nil || app.ClientSecret != clientSecret { if app == nil || app.ClientSecret != clientSecret {
return "" return ""
} }
return app.Organization+"/"+app.Name return app.Organization + "/" + app.Name
} }
func RecordMessage(ctx *context.Context) { func RecordMessage(ctx *context.Context) {
if ctx.Request.URL.Path != "/api/login" { if ctx.Request.URL.Path != "/api/login" {
user := getUser(ctx) user := getUser(ctx)
userinfo := strings.Split(user,"/") userinfo := strings.Split(user, "/")
if user == "" { if user == "" {
userinfo = append(userinfo,"") userinfo = append(userinfo, "")
} }
record := util.Records(ctx) record := util.Records(ctx)
record.Organization = userinfo[0] record.Organization = userinfo[0]
@@ -67,4 +67,3 @@ func RecordMessage(ctx *context.Context) {
object.AddRecord(record) object.AddRecord(record)
} }
} }

View File

@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package routers
// @APIVersion 1.0.0 // @APIVersion 1.0.0
// @Title Casdoor API // @Title Casdoor API
// @Description Documentation of Casdoor API // @Description Documentation of Casdoor API
@@ -99,4 +100,3 @@ func initAPI() {
beego.Router("/api/send-email", &controllers.ApiController{}, "POST:SendEmail") beego.Router("/api/send-email", &controllers.ApiController{}, "POST:SendEmail")
beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms") beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms")
} }

View File

@@ -21,12 +21,12 @@ import (
) )
type Record struct { type Record struct {
ClientIp string `xorm:"varchar(100)" json:"clientIp"` ClientIp string `xorm:"varchar(100)" json:"clientIp"`
Timestamp string `xorm:"varchar(100)" json:"timestamp"` Timestamp string `xorm:"varchar(100)" json:"timestamp"`
Organization string `xorm:"varchar(100)" json:"organization"` Organization string `xorm:"varchar(100)" json:"organization"`
Username string `xorm:"varchar(100)" json:"username"` Username string `xorm:"varchar(100)" json:"username"`
RequestUri string `xorm:"varchar(1000)" json:"requestUri"` RequestUri string `xorm:"varchar(1000)" json:"requestUri"`
Action string `xorm:"varchar(1000)" json:"action"` Action string `xorm:"varchar(1000)" json:"action"`
} }
func Records(ctx *context.Context) *Record { func Records(ctx *context.Context) *Record {

View File

@@ -23,7 +23,7 @@ var rePhoneCn *regexp.Regexp
func init() { func init() {
// https://learnku.com/articles/31543 // https://learnku.com/articles/31543
rePhoneCn, _ = regexp.Compile("^1(3\\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\\d|9[0-35-9])\\d{8}$") rePhoneCn, _ = regexp.Compile(`^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$`)
} }
func IsEmailValid(email string) bool { func IsEmailValid(email string) bool {