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
====
[![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.
## 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/
- Source code: https://github.com/casbin/casdoor (this repo)
Run your own casdoor program in a few minutes:smiley:
Global admin login:
### Download
- Username: `admin`
- Password: `123`
There are two methods, get code via go subcommand `get`:
### 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/
- Source code: https://github.com/casbin/casbin-oa
```bash
git clone https://github.com/casbin/casdoor
```
## Architecture
Finally, change directory:
Casdoor contains 2 parts:
```bash
cd casdoor/
```
Name | Description | Language | Source code
----|------|----|----
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
We provide two start up methods for all kinds of users.
## Installation
### Manual
- Get code via `go get`:
#### Simple configuration
```shell
go get github.com/casbin/casdoor
```
Edit `conf/app.conf`, modify `dataSourceName` to correct database info, which follows this format:
or `git clone`:
```bash
username:password@tcp(database_ip:database_port)/
```
```shell
git clone https://github.com/casbin/casdoor
```
#### Run
## Run through Docker
- 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:
Casdoor provides two run modes, the difference is binary size and user prompt.
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
go run main.go
```
Then build back-end binary file, change directory to root(Relative to casdoor):
- Run frontend (in the same machine's port 7001):
```bash
go run main.go
```
```shell
cd web
## npm
npm install
npm run start
## yarn
yarn install
yarn run start
```
That's it! Try to visit http://127.0.0.1:7001/. :small_airplane:
- 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):
```
cd web
## npm
npm run build
## yarn
yarn run build
## back to casdoor directory
cd ..
```
```bash
go build main.go && sudo ./main
```
- build and run go code:
> Notice, you should visit back-end port, default 8000. Now try to visit http://127.0.0.1:8000/
```
go build
./casdoor
```
### Docker
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
db = mysql
dataSourceName = root:123@tcp(localhost:3306)/
dbName = casdoor
```
> If you need to modify `conf/app.conf`, you need to re-run `docker-compose up`.
- 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
db = postgres
dataSourceName = "user=postgres password=xxx sslmode=disable dbname="
dbName = casdoor
```
```bash
docker-compose up
```
**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.
You could set `ShowGithubCorner` to hidden it.
## Other examples
Configuration (`web/src/commo/Conf.js`):
These all use casdoor as a centralized authentication platform.
```javascript
export const ShowGithubCorner = true
- [Casnode](https://github.com/casbin/casnode): Next-generation forum software based on React + Golang.
- [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"`
}
// Signup
// @Title Signup
// @Description sign up a new user
// @Param username formData string true "The username to sign up"
@ -178,6 +179,7 @@ func (c *ApiController) Signup() {
c.ServeJSON()
}
// Logout
// @Title Logout
// @Description logout the current user
// @Success 200 {object} controllers.Response The Response object
@ -197,6 +199,7 @@ func (c *ApiController) Logout() {
c.ServeJSON()
}
// GetAccount
// @Title GetAccount
// @Description get the details of the current account
// @Success 200 {object} controllers.Response The Response object
@ -224,6 +227,7 @@ func (c *ApiController) GetAccount() {
c.ServeJSON()
}
// UploadAvatar
// @Title UploadAvatar
// @Description upload avatar
// @Param avatarfile formData string true "The base64 encode of avatarfile"
@ -272,6 +276,7 @@ func (c *ApiController) UploadAvatar() {
c.ServeJSON()
}
// GetHumanCheck ...
func (c *ApiController) GetHumanCheck() {
c.Data["json"] = HumanCheck{Type: "none"}

View File

@ -20,6 +20,7 @@ import (
"github.com/casbin/casdoor/object"
)
// GetApplications
// @Title GetApplications
// @Description get all applications
// @Param owner query string true "The owner of applications."
@ -32,6 +33,7 @@ func (c *ApiController) GetApplications() {
c.ServeJSON()
}
// GetApplication
// @Title GetApplication
// @Description get the detail of an application
// @Param id query string true "The id of the application."
@ -44,6 +46,7 @@ func (c *ApiController) GetApplication() {
c.ServeJSON()
}
// GetUserApplication
// @Title GetUserApplication
// @Description get the detail of the user's application
// @Param id query string true "The id of the user"
@ -61,6 +64,7 @@ func (c *ApiController) GetUserApplication() {
c.ServeJSON()
}
// UpdateApplication
// @Title UpdateApplication
// @Description update an application
// @Param id query string true "The id of the application"
@ -80,6 +84,7 @@ func (c *ApiController) UpdateApplication() {
c.ServeJSON()
}
// AddApplication
// @Title AddApplication
// @Description add an application
// @Param body body object.Application true "The details of the application"
@ -96,6 +101,7 @@ func (c *ApiController) AddApplication() {
c.ServeJSON()
}
// DeleteApplication
// @Title DeleteApplication
// @Description delete an 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 {
if 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()
resp := &Response{}
if form.Type == ResponseTypeLogin {
c.SetSessionUsername(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
}
// GetApplicationLogin ...
// @Title GetApplicationLogin
// @Description get application login
// @Param clientId query string true "client id"
@ -108,6 +109,7 @@ func setHttpClient(idProvider idp.IdProvider, providerType string) {
}
}
// Login ...
// @Title Login
// @Description login
// @Param oAuthParams query string true "oAuth parameters"
@ -182,13 +184,11 @@ func (c *ApiController) Login() {
c.ResponseError("wrong email!")
}
object.DisableVerificationCode(form.Email)
break
case "phone":
if user.Phone != form.Email {
c.ResponseError("wrong phone!")
}
object.DisableVerificationCode(form.Email)
break
}
} else {
password := form.Password
@ -282,7 +282,7 @@ func (c *ApiController) Login() {
record.Organization = application.Organization
record.Username = user.Name
object.AddRecord(record)
object.AddRecord(record)
} else {
// Sign up via OAuth
if !application.EnableSignUp {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,7 @@ import (
sender "github.com/casdoor/go-sms-sender"
)
// SendEmail
// @Title SendEmail
// @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"
@ -84,8 +85,7 @@ func (c *ApiController) SendEmail() {
emailForm.Title,
emailForm.Content,
receiver,
emailForm.Sender);
len(msg) == 0 {
emailForm.Sender); len(msg) == 0 {
ok++
}
}
@ -94,6 +94,7 @@ func (c *ApiController) SendEmail() {
c.ServeJSON()
}
// SendSms
// @Title SendSms
// @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"
@ -148,7 +149,7 @@ func (c *ApiController) SendSms() {
}
}
if len(invalidReceivers) != 0{
if len(invalidReceivers) != 0 {
c.ResponseError("Invalid phone numbers", invalidReceivers)
return
}

View File

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

View File

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

View File

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

View File

@ -33,6 +33,7 @@ func (c *ApiController) getCurrentUser() *object.User {
return user
}
// SendVerificationCode ...
func (c *ApiController) SendVerificationCode() {
destType := c.Ctx.Request.Form.Get("type")
dest := c.Ctx.Request.Form.Get("dest")
@ -42,7 +43,7 @@ func (c *ApiController) SendVerificationCode() {
checkKey := c.Ctx.Request.Form.Get("checkKey")
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.")
return
}
@ -97,6 +98,7 @@ func (c *ApiController) SendVerificationCode() {
c.ServeJSON()
}
// ResetEmailOrPhone ...
func (c *ApiController) ResetEmailOrPhone() {
userId, ok := c.RequireSignedIn()
if !ok {

2
go.mod
View File

@ -23,7 +23,7 @@ require (
github.com/satori/go.uuid v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
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/time v0.0.0-20210220033141-f8bda1e9f3ba // 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-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-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-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-20190226205417-e64efc72b421/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-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-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-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.3.0/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"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -48,6 +47,7 @@ type DingTalkIdProvider struct {
Config *oauth2.Config
}
// NewDingTalkIdProvider ...
func NewDingTalkIdProvider(clientId string, clientSecret string, redirectUrl string) *DingTalkIdProvider {
idp := &DingTalkIdProvider{}
@ -57,6 +57,7 @@ func NewDingTalkIdProvider(clientId string, clientSecret string, redirectUrl str
return idp
}
// SetHttpClient ...
func (idp *DingTalkIdProvider) SetHttpClient(client *http.Client) {
idp.Client = client
}
@ -136,7 +137,7 @@ func (idp *DingTalkIdProvider) GetToken(code string) (*oauth2.Token, error) {
_ = json.Unmarshal(body, &info)
errCode := info.Errcode
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)
@ -151,7 +152,7 @@ func (idp *DingTalkIdProvider) GetToken(code string) (*oauth2.Token, error) {
tokenResp := DingTalkAccessToken{}
_ = json.Unmarshal(body, &tokenResp)
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
@ -183,6 +184,7 @@ type UnionIdResponse struct {
RequestId string `json:"request_id"`
}
// GetUseridByUnionid ...
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",
accesstoken, unionid)
@ -195,7 +197,7 @@ func (idp *DingTalkIdProvider) GetUseridByUnionid(accesstoken, unionid string) (
_ = json.Unmarshal([]byte(useridInfo), &uresp)
errcode := uresp.Errcode
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
}

View File

@ -61,7 +61,7 @@ func (idp *GithubIdProvider) getConfig() *oauth2.Config {
}
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)
}

View File

@ -61,7 +61,7 @@ func (idp *GoogleIdProvider) getConfig() *oauth2.Config {
}
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)
}

View File

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

View File

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

View File

@ -173,7 +173,7 @@ func (idp *QqIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
}
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{

View File

@ -99,7 +99,7 @@ func (idp *WeChatIdProvider) GetToken(code string) (*oauth2.Token, error) {
}
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
}
@ -168,7 +168,7 @@ func (idp *WeChatIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
if err != nil {
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
}

View File

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

View File

@ -24,7 +24,7 @@ import (
var reWhiteSpace *regexp.Regexp
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 {

View File

@ -152,43 +152,30 @@ func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
switch attribute.Name {
case "uidNumber":
ldapUserItem.UidNumber = attribute.Values[0]
break
case "uid":
ldapUserItem.Uid = attribute.Values[0]
break
case "cn":
ldapUserItem.Cn = attribute.Values[0]
break
case "gidNumber":
ldapUserItem.GidNumber = attribute.Values[0]
break
case "entryUUID":
ldapUserItem.Uuid = attribute.Values[0]
break
case "mail":
ldapUserItem.Mail = attribute.Values[0]
break
case "email":
ldapUserItem.Email = attribute.Values[0]
break
case "emailAddress":
ldapUserItem.EmailAddress = attribute.Values[0]
break
case "telephoneNumber":
ldapUserItem.TelephoneNumber = attribute.Values[0]
break
case "mobile":
ldapUserItem.Mobile = attribute.Values[0]
break
case "mobileTelephoneNumber":
ldapUserItem.MobileTelephoneNumber = attribute.Values[0]
break
case "registeredAddress":
ldapUserItem.RegisteredAddress = attribute.Values[0]
break
case "postalAddress":
ldapUserItem.PostalAddress = attribute.Values[0]
break
}
}
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 {
panic(err)
}

View File

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

View File

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

View File

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

View File

@ -16,6 +16,7 @@ package object
import (
"fmt"
"reflect"
"testing"
"github.com/casbin/casdoor/util"
@ -78,3 +79,27 @@ func TestGetSaltedPassword(t *testing.T) {
salt := "123"
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 {
return ""
}
return app.Organization+"/"+app.Name
return app.Organization + "/" + app.Name
}
func RecordMessage(ctx *context.Context) {
if ctx.Request.URL.Path != "/api/login" {
user := getUser(ctx)
userinfo := strings.Split(user,"/")
userinfo := strings.Split(user, "/")
if user == "" {
userinfo = append(userinfo,"")
userinfo = append(userinfo, "")
}
record := util.Records(ctx)
record.Organization = userinfo[0]
@ -67,4 +67,3 @@ func RecordMessage(ctx *context.Context) {
object.AddRecord(record)
}
}

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package routers
// @APIVersion 1.0.0
// @Title 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-sms", &controllers.ApiController{}, "POST:SendSms")
}

View File

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

View File

@ -23,7 +23,7 @@ var rePhoneCn *regexp.Regexp
func init() {
// 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 {