Skip to content

Commit dc41382

Browse files
committed
Merge branch 'feat/api-projects' of https://github.com/dineshsalunke/gitea into feat/api-projects
2 parents fdf716c + 5a6a10e commit dc41382

File tree

11 files changed

+303
-181
lines changed

11 files changed

+303
-181
lines changed

models/auth/access_token_scope.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const (
2424
AccessTokenScopeCategoryIssue
2525
AccessTokenScopeCategoryRepository
2626
AccessTokenScopeCategoryUser
27+
AccessTokenScopeCategoryProject
2728
)
2829

2930
// AllAccessTokenScopeCategories contains all access token scope categories
@@ -37,6 +38,7 @@ var AllAccessTokenScopeCategories = []AccessTokenScopeCategory{
3738
AccessTokenScopeCategoryIssue,
3839
AccessTokenScopeCategoryRepository,
3940
AccessTokenScopeCategoryUser,
41+
AccessTokenScopeCategoryProject,
4042
}
4143

4244
// AccessTokenScopeLevel represents the access levels without a given scope category
@@ -82,6 +84,9 @@ const (
8284

8385
AccessTokenScopeReadUser AccessTokenScope = "read:user"
8486
AccessTokenScopeWriteUser AccessTokenScope = "write:user"
87+
88+
AccessTokenScopeReadProject AccessTokenScope = "read:project"
89+
AccessTokenScopeWriteProject AccessTokenScope = "write:project"
8590
)
8691

8792
// accessTokenScopeBitmap represents a bitmap of access token scopes.
@@ -124,6 +129,9 @@ const (
124129
accessTokenScopeReadUserBits accessTokenScopeBitmap = 1 << iota
125130
accessTokenScopeWriteUserBits accessTokenScopeBitmap = 1<<iota | accessTokenScopeReadUserBits
126131

132+
accessTokenScopeReadProjectBits accessTokenScopeBitmap = 1 << iota
133+
accessTokenScopeWriteProjectBits accessTokenScopeBitmap = 1<<iota | accessTokenScopeReadProjectBits
134+
127135
// The current implementation only supports up to 64 token scopes.
128136
// If we need to support > 64 scopes,
129137
// refactoring the whole implementation in this file (and only this file) is needed.
@@ -142,6 +150,7 @@ var allAccessTokenScopes = []AccessTokenScope{
142150
AccessTokenScopeWriteIssue, AccessTokenScopeReadIssue,
143151
AccessTokenScopeWriteRepository, AccessTokenScopeReadRepository,
144152
AccessTokenScopeWriteUser, AccessTokenScopeReadUser,
153+
AccessTokenScopeWriteProject, AccessTokenScopeReadProject,
145154
}
146155

147156
// allAccessTokenScopeBits contains all access token scopes.
@@ -166,6 +175,8 @@ var allAccessTokenScopeBits = map[AccessTokenScope]accessTokenScopeBitmap{
166175
AccessTokenScopeWriteRepository: accessTokenScopeWriteRepositoryBits,
167176
AccessTokenScopeReadUser: accessTokenScopeReadUserBits,
168177
AccessTokenScopeWriteUser: accessTokenScopeWriteUserBits,
178+
AccessTokenScopeReadProject: accessTokenScopeReadProjectBits,
179+
AccessTokenScopeWriteProject: accessTokenScopeWriteProjectBits,
169180
}
170181

171182
// readAccessTokenScopes maps a scope category to the read permission scope
@@ -180,6 +191,7 @@ var accessTokenScopes = map[AccessTokenScopeLevel]map[AccessTokenScopeCategory]A
180191
AccessTokenScopeCategoryIssue: AccessTokenScopeReadIssue,
181192
AccessTokenScopeCategoryRepository: AccessTokenScopeReadRepository,
182193
AccessTokenScopeCategoryUser: AccessTokenScopeReadUser,
194+
AccessTokenScopeCategoryProject: AccessTokenScopeReadProject,
183195
},
184196
Write: {
185197
AccessTokenScopeCategoryActivityPub: AccessTokenScopeWriteActivityPub,
@@ -191,6 +203,7 @@ var accessTokenScopes = map[AccessTokenScopeLevel]map[AccessTokenScopeCategory]A
191203
AccessTokenScopeCategoryIssue: AccessTokenScopeWriteIssue,
192204
AccessTokenScopeCategoryRepository: AccessTokenScopeWriteRepository,
193205
AccessTokenScopeCategoryUser: AccessTokenScopeWriteUser,
206+
AccessTokenScopeCategoryProject: AccessTokenScopeWriteProject,
194207
},
195208
}
196209

models/auth/access_token_scope_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type scopeTestNormalize struct {
1717
}
1818

1919
func TestAccessTokenScope_Normalize(t *testing.T) {
20-
assert.Equal(t, []string{"activitypub", "admin", "issue", "misc", "notification", "organization", "package", "repository", "user"}, GetAccessTokenCategories())
20+
assert.Equal(t, []string{"activitypub", "admin", "issue", "misc", "notification", "organization", "package", "project", "repository", "user"}, GetAccessTokenCategories())
2121
tests := []scopeTestNormalize{
2222
{"", "", nil},
2323
{"write:misc,write:notification,read:package,write:notification,public-only", "public-only,write:misc,write:notification,read:package", nil},

models/project/column.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ const (
3434
CardTypeImagesAndText
3535
)
3636

37+
func (p CardType) ToString() string {
38+
switch p {
39+
case CardTypeImagesAndText:
40+
return "ImagesAndText"
41+
case CardTypeTextOnly:
42+
fallthrough
43+
default:
44+
return "TextOnly"
45+
}
46+
}
47+
48+
func ToCardType(s string) CardType {
49+
switch s {
50+
case "ImagesAndText":
51+
return CardTypeImagesAndText
52+
case "TextOnly":
53+
fallthrough
54+
default:
55+
return CardTypeTextOnly
56+
}
57+
}
58+
3759
// ColumnColorPattern is a regexp witch can validate ColumnColor
3860
var ColumnColorPattern = regexp.MustCompile("^#[0-9a-fA-F]{6}$")
3961

models/project/template.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@ const (
2525
TemplateTypeBugTriage
2626
)
2727

28+
func (p TemplateType) ToString() string {
29+
switch p {
30+
case TemplateTypeBasicKanban:
31+
return "BasicKanban"
32+
case TemplateTypeBugTriage:
33+
return "BugTriage"
34+
case TemplateTypeNone:
35+
fallthrough
36+
default:
37+
return ""
38+
}
39+
}
40+
41+
// ToTemplateType converts a string to a TemplateType
42+
func ToTemplateType(s string) TemplateType {
43+
switch s {
44+
case "BasicKanban":
45+
return TemplateTypeBasicKanban
46+
case "BugTriage":
47+
return TemplateTypeBugTriage
48+
default:
49+
return TemplateTypeNone
50+
}
51+
}
52+
2853
// GetTemplateConfigs retrieves the template configs of configurations project columns could have
2954
func GetTemplateConfigs() []TemplateConfig {
3055
return []TemplateConfig{

modules/structs/project.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,53 @@ package structs
55

66
import "time"
77

8+
// NewProjectOption options when creating a new project
89
// swagger:model
9-
type NewProjectPayload struct {
10+
type NewProjectOption struct {
1011
// required:true
11-
Title string `json:"title" binding:"Required"`
12+
// Keep compatibility with Github API to use "name" instead of "title"
13+
Name string `json:"name" binding:"Required"`
1214
// required:true
13-
BoardType uint8 `json:"board_type"`
15+
// enum: , BasicKanban, BugTriage
16+
// Note: this is the same as TemplateType in models/project/template.go
17+
TemplateType string `json:"template_type"`
1418
// required:true
15-
CardType uint8 `json:"card_type"`
16-
Description string `json:"description"`
19+
// enum: TextOnly, ImagesAndText
20+
CardType string `json:"card_type"`
21+
// Keep compatibility with Github API to use "body" instead of "description"
22+
Body string `json:"body"`
1723
}
1824

25+
// UpdateProjectOption options when updating a project
1926
// swagger:model
20-
type UpdateProjectPayload struct {
27+
type UpdateProjectOption struct {
2128
// required:true
22-
Title string `json:"title" binding:"Required"`
23-
Description string `json:"description"`
29+
// Keep compatibility with Github API to use "name" instead of "title"
30+
Name string `json:"name" binding:"Required"`
31+
// Keep compatibility with Github API to use "body" instead of "description"
32+
Body string `json:"body"`
2433
}
2534

35+
// Project represents a project
2636
// swagger:model
2737
type Project struct {
28-
ID int64 `json:"id"`
29-
Title string `json:"title"`
30-
Description string `json:"description"`
31-
TemplateType uint8 `json:"board_type"`
32-
IsClosed bool `json:"is_closed"`
38+
ID int64 `json:"id"`
39+
// Keep compatibility with Github API to use "name" instead of "title"
40+
Name string `json:"name"`
41+
// Keep compatibility with Github API to use "body" instead of "description"
42+
Body string `json:"body"`
43+
// required:true
44+
// enum: , BasicKanban, BugTriage
45+
// Note: this is the same as TemplateType in models/project/template.go
46+
TemplateType string `json:"template_type"`
47+
// enum: open, closed
48+
State string `json:"state"`
3349
// swagger:strfmt date-time
3450
Created time.Time `json:"created_at"`
3551
// swagger:strfmt date-time
3652
Updated time.Time `json:"updated_at"`
3753
// swagger:strfmt date-time
38-
Closed time.Time `json:"closed_at"`
54+
Closed *time.Time `json:"closed_at"`
3955

4056
Repo *RepositoryMeta `json:"repository"`
4157
Creator *User `json:"creator"`

routers/api/v1/api.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,13 @@ func Routes() *web.Router {
10421042

10431043
m.Get("/subscriptions", user.GetWatchedRepos)
10441044
}, context.UserAssignmentAPI(), checkTokenPublicOnly())
1045+
1046+
m.Group("/{username}", func() {
1047+
m.Group("/projects", func() {
1048+
m.Get("", projects.ListUserProjects)
1049+
m.Post("", bind(api.NewProjectOption{}), projects.CreateUserProject)
1050+
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryProject))
1051+
}, context.UserAssignmentAPI())
10451052
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
10461053

10471054
// Users (requires user scope)
@@ -1162,11 +1169,6 @@ func Routes() *web.Router {
11621169
m.Delete("", user.UnblockUser)
11631170
}, context.UserAssignmentAPI(), checkTokenPublicOnly())
11641171
})
1165-
1166-
m.Group("/projects", func() {
1167-
m.Get("", projects.ListUserProjects)
1168-
m.Post("", bind(api.NewProjectPayload{}), projects.CreateUserProject)
1169-
})
11701172
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
11711173

11721174
// Repositories (requires repo scope, org scope)
@@ -1475,8 +1477,8 @@ func Routes() *web.Router {
14751477
m.Methods("HEAD,GET", "/{ball_type:tarball|zipball|bundle}/*", reqRepoReader(unit.TypeCode), repo.DownloadArchive)
14761478

14771479
m.Group("/projects", func() {
1478-
m.Post("", bind(api.NewProjectPayload{}), projects.CreateRepoProject)
1479-
})
1480+
m.Post("", bind(api.NewProjectOption{}), projects.CreateRepoProject)
1481+
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryProject))
14801482
}, repoAssignment(), checkTokenPublicOnly())
14811483
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
14821484

@@ -1699,9 +1701,9 @@ func Routes() *web.Router {
16991701
}, reqToken(), reqOrgOwnership())
17001702

17011703
m.Group("/projects", func() {
1702-
m.Post("", bind(api.NewProjectPayload{}), projects.CreateOrgProject)
1704+
m.Post("", bind(api.NewProjectOption{}), projects.CreateOrgProject)
17031705
m.Get("", projects.ListOrgProjects)
1704-
})
1706+
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryProject))
17051707
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true), checkTokenPublicOnly())
17061708
m.Group("/teams/{teamid}", func() {
17071709
m.Combo("").Get(reqToken(), org.GetTeam).
@@ -1724,6 +1726,13 @@ func Routes() *web.Router {
17241726
m.Get("/activities/feeds", org.ListTeamActivityFeeds)
17251727
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(false, true), reqToken(), reqTeamMembership(), checkTokenPublicOnly())
17261728

1729+
// Projects
1730+
m.Group("/projects", func() {
1731+
m.Get("{project_id}", projects.GetProject)
1732+
m.Patch("{project_id}", bind(api.UpdateProjectOption{}), projects.UpdateProject)
1733+
m.Delete("{project_id}", projects.DeleteProject)
1734+
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryProject), reqToken())
1735+
17271736
m.Group("/admin", func() {
17281737
m.Group("/cron", func() {
17291738
m.Get("", admin.ListCronTasks)

0 commit comments

Comments
 (0)