// Parse parses the scope string into a bitmap, thus removing possible duplicates.
func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) {
- list := strings.Split(string(s), ",")
-
var bitmap AccessTokenScopeBitmap
- for _, v := range list {
+
+ // The following is the more performant equivalent of 'for _, v := range strings.Split(remainingScope, ",")' as this is hot code
+ remainingScopes := string(s)
+ for len(remainingScopes) > 0 {
+ i := strings.IndexByte(remainingScopes, ',')
+ var v string
+ if i < 0 {
+ v = remainingScopes
+ remainingScopes = ""
+ } else if i+1 >= len(remainingScopes) {
+ v = remainingScopes[:i]
+ remainingScopes = ""
+ } else {
+ v = remainingScopes[:i]
+ remainingScopes = remainingScopes[i+1:]
+ }
singleScope := AccessTokenScope(v)
if singleScope == "" {
continue
}
bitmap |= bits
}
+
return bitmap, nil
}
+// StringSlice returns the AccessTokenScope as a []string
+func (s AccessTokenScope) StringSlice() []string {
+ return strings.Split(string(s), ",")
+}
+
// Normalize returns a normalized scope string without any duplicates.
func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
bitmap, err := s.Parse()
// AccessToken represents an API access token.
// swagger:response AccessToken
type AccessToken struct {
- ID int64 `json:"id"`
- Name string `json:"name"`
- Token string `json:"sha1"`
- TokenLastEight string `json:"token_last_eight"`
+ ID int64 `json:"id"`
+ Name string `json:"name"`
+ Token string `json:"sha1"`
+ TokenLastEight string `json:"token_last_eight"`
+ Scopes []string `json:"scopes"`
}
// AccessTokenList represents a list of API access token.
type AccessTokenList []*AccessToken
// CreateAccessTokenOption options when create access token
-// swagger:parameters userCreateToken
type CreateAccessTokenOption struct {
- Name string `json:"name" binding:"Required"`
+ // required: true
+ Name string `json:"name" binding:"Required"`
+ Scopes []string `json:"scopes"`
}
// CreateOAuth2ApplicationOptions holds options to create an oauth2 application
access_token_deletion_desc = Deleting a token will revoke access to your account for applications using it. This cannot be undone. Continue?
delete_token_success = The token has been deleted. Applications using it no longer have access to your account.
select_scopes = Select scopes
+scopes_list = Scopes:
manage_oauth2_applications = Manage OAuth2 Applications
edit_oauth2_application = Edit OAuth2 Application
"fmt"
"net/http"
"strconv"
+ "strings"
auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/context"
ID: tokens[i].ID,
Name: tokens[i].Name,
TokenLastEight: tokens[i].TokenLastEight,
+ Scopes: tokens[i].Scope.StringSlice(),
}
}
// - name: username
// in: path
// description: username of user
- // type: string
// required: true
- // - name: userCreateToken
+ // type: string
+ // - name: body
// in: body
// schema:
// "$ref": "#/definitions/CreateAccessTokenOption"
return
}
+ scope, err := auth_model.AccessTokenScope(strings.Join(form.Scopes, ",")).Normalize()
+ if err != nil {
+ ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err))
+ return
+ }
+ t.Scope = scope
+
if err := auth_model.NewAccessToken(t); err != nil {
ctx.Error(http.StatusInternalServerError, "NewAccessToken", err)
return
"parameters": [
{
"type": "string",
- "x-go-name": "Name",
"description": "username of user",
"name": "username",
"in": "path",
"required": true
},
{
- "name": "userCreateToken",
+ "name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/CreateAccessTokenOption"
"type": "string",
"x-go-name": "Name"
},
+ "scopes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "x-go-name": "Scopes"
+ },
"sha1": {
"type": "string",
"x-go-name": "Token"
"CreateAccessTokenOption": {
"description": "CreateAccessTokenOption options when create access token",
"type": "object",
+ "required": [
+ "name"
+ ],
"properties": {
"name": {
"type": "string",
"x-go-name": "Name"
+ },
+ "scopes": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "x-go-name": "Scopes"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
</div>
<i class="icon tooltip{{if .HasRecentActivity}} green{{end}}" {{if .HasRecentActivity}}data-content="{{$.locale.Tr "settings.token_state_desc"}}"{{end}}>{{svg "fontawesome-send" 36}}</i>
<div class="content">
- <strong>{{.Name}}</strong>
+ <details><summary><strong>{{.Name}}</strong></summary>
+ <p class="gt-my-2">{{$.locale.Tr "settings.scopes_list"}}</p>
+ <ul class="gt-my-2">
+ {{range .Scope.StringSlice}}
+ <li>{{.}}</li>
+ {{end}}
+ </ul>
+ </details>
<div class="activity meta">
<i>{{$.locale.Tr "settings.add_on"}} <span><time data-format="short-date" datetime="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</time></span> — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}><time data-format="short-date" datetime="{{.UpdatedUnix.FormatLong}}">{{.UpdatedUnix.FormatShort}}</time></span>{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}}</i>
</div>