Skip to content
This repository has been archived by the owner on Oct 2, 2020. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #17 from bored-engineer/program
Add ProgramService and update related structs
  • Loading branch information
aegarbutt committed Dec 12, 2016
2 parents 97b976b + bfa7b29 commit bc8cb11
Show file tree
Hide file tree
Showing 16 changed files with 675 additions and 12 deletions.
63 changes: 63 additions & 0 deletions _examples/getProgram/main.go
@@ -0,0 +1,63 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

import (
"github.com/uber-go/hackeroni/h1"

"golang.org/x/crypto/ssh/terminal"

"bufio"
"fmt"
"os"
"strings"
"syscall"
)

func main() {

fmt.Print("HackerOne API Identifier: ")
r := bufio.NewReader(os.Stdin)
identifier, _ := r.ReadString('\n')

fmt.Print("HackerOne API Token: ")
token, _ := terminal.ReadPassword(int(syscall.Stdin))
fmt.Print("\n")

tp := h1.APIAuthTransport{
APIIdentifier: strings.TrimSpace(identifier),
APIToken: strings.TrimSpace(string(token)),
}

client := h1.NewClient(tp.Client())

fmt.Print("Program ID: ")
programID, _ := r.ReadString('\n')
fmt.Print("\n")

program, _, err := client.Program.Get(strings.TrimSpace(programID))
if err != nil {
panic(err)
}

fmt.Printf("Program: %#v\n", program)

}
49 changes: 49 additions & 0 deletions h1/activity_test.go
Expand Up @@ -93,6 +93,55 @@ func Test_ActivityActor_Program(t *testing.T) {
Handle: String("security"),
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
UpdatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
Groups: []*Group{
&Group{
ID: String("2557"),
Type: String(GroupType),
Name: String("Standard"),
Permissions: []*string{
String(GroupPermissionReportManagement),
String(GroupPermissionRewardManagement),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
},
&Group{
ID: String("2558"),
Type: String(GroupType),
Name: String("Admin"),
Permissions: []*string{
String(GroupPermissionUserManagement),
String(GroupPermissionProgramManagement),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
},
},
Members: []*Member{
&Member{
ID: String("1339"),
Type: String(MemberType),
Permissions: []*string{
String(MemberPermissionProgramManagement),
String(MemberPermissionReportManagement),
String(MemberPermissionRewardManagement),
String(MemberPermissionUserManagement),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
User: &User{
ID: String("1337"),
Type: String(UserType),
Disabled: Bool(false),
Username: String("api-example"),
Name: String("API Example"),
ProfilePicture: UserProfilePicture{
Size62x62: String("/assets/avatars/default.png"),
Size82x82: String("/assets/avatars/default.png"),
Size110x110: String("/assets/avatars/default.png"),
Size260x260: String("/assets/avatars/default.png"),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
},
},
},
}
assert.Equal(t, expectedActor, actualActor)
}
Expand Down
19 changes: 15 additions & 4 deletions h1/group.go
Expand Up @@ -24,14 +24,25 @@ import (
"encoding/json"
)

// GroupPermission represent possible permissions sizes for a group
//
// HackerOne API docs: https://api.hackerone.com/docs/v1#group
const (
GroupPermissionRewardManagement string = "reward_management"
GroupPermissionProgramManagement string = "program_management"
GroupPermissionUserManagement string = "user_management"
GroupPermissionReportManagement string = "report_management"
)

// Group represents a group of users.
//
// HackerOne API docs: https://api.hackerone.com/docs/v1#group
type Group struct {
ID *string `json:"id"`
Type *string `json:"type"`
Name *string `json:"name"`
CreatedAt *Timestamp `json:"created_at"`
ID *string `json:"id"`
Type *string `json:"type"`
Name *string `json:"name"`
Permissions []*string `json:"permissions"`
CreatedAt *Timestamp `json:"created_at"`
}

// Helper types for JSONUnmarshal
Expand Down
10 changes: 7 additions & 3 deletions h1/group_test.go
Expand Up @@ -30,9 +30,13 @@ func Test_Group(t *testing.T) {
var actual Group
loadResource(t, &actual, "tests/resources/group.json")
expected := Group{
ID: String("1337"),
Type: String(GroupType),
Name: String("Admin"),
ID: String("1337"),
Type: String(GroupType),
Name: String("Admin"),
Permissions: []*string{
String(GroupPermissionUserManagement),
String(GroupPermissionReportManagement),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
}
assert.Equal(t, expected, actual)
Expand Down
4 changes: 3 additions & 1 deletion h1/h1.go
Expand Up @@ -51,7 +51,8 @@ type Client struct {
common service // Reuse a single struct instead of allocating one for each service on the heap.

// Services used for talking to different parts of the H1 API.
Report *ReportService
Report *ReportService
Program *ProgramService
}

type service struct {
Expand Down Expand Up @@ -103,6 +104,7 @@ func NewClient(httpClient *http.Client) *Client {
c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent}
c.common.client = c
c.Report = (*ReportService)(&c.common)
c.Program = (*ProgramService)(&c.common)

return c
}
Expand Down
70 changes: 70 additions & 0 deletions h1/member.go
@@ -0,0 +1,70 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package h1

import (
"encoding/json"
)

// MemberPermission represent possible permissions sizes for a member
//
// HackerOne API docs: https://api.hackerone.com/docs/v1#member
const (
MemberPermissionRewardManagement string = "reward_management"
MemberPermissionProgramManagement string = "program_management"
MemberPermissionUserManagement string = "user_management"
MemberPermissionReportManagement string = "report_management"
)

// Member represents a user in a program
//
// HackerOne API docs: https://api.hackerone.com/docs/v1#member
type Member struct {
ID *string `json:"id"`
Type *string `json:"type"`
Permissions []*string `json:"permissions"`
CreatedAt *Timestamp `json:"created_at"`
User *User `json:"user"`
}

// Helper types for JSONUnmarshal
type member Member // Used to avoid recursion of JSONUnmarshal
type memberUnmarshalHelper struct {
member
Attributes *member `json:"attributes"`
Relationships struct {
User struct {
Data *User `json:"data"`
} `json:"user"`
} `json:"relationships"`
}

// UnmarshalJSON allows JSONAPI attributes and relationships to unmarshal cleanly.
func (m *Member) UnmarshalJSON(b []byte) error {
var helper memberUnmarshalHelper
helper.Attributes = &helper.member
if err := json.Unmarshal(b, &helper); err != nil {
return err
}
*m = Member(helper.member)
m.User = helper.Relationships.User.Data
return nil
}
58 changes: 58 additions & 0 deletions h1/member_test.go
@@ -0,0 +1,58 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package h1

import (
"github.com/stretchr/testify/assert"

"testing"
)

func Test_Member(t *testing.T) {
var actual Member
loadResource(t, &actual, "tests/resources/member.json")
expected := Member{
ID: String("1337"),
Type: String(MemberType),
Permissions: []*string{
String(MemberPermissionProgramManagement),
String(MemberPermissionReportManagement),
String(MemberPermissionRewardManagement),
String(MemberPermissionUserManagement),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
User: &User{
ID: String("1337"),
Type: String(UserType),
Disabled: Bool(false),
Username: String("api-example"),
Name: String("API Example"),
ProfilePicture: UserProfilePicture{
Size62x62: String("/assets/avatars/default.png"),
Size82x82: String("/assets/avatars/default.png"),
Size110x110: String("/assets/avatars/default.png"),
Size260x260: String("/assets/avatars/default.png"),
},
CreatedAt: NewTimestamp("2016-02-02T04:05:06.000Z"),
},
}
assert.Equal(t, expected, actual)
}
14 changes: 13 additions & 1 deletion h1/program.go
Expand Up @@ -33,13 +33,23 @@ type Program struct {
Handle *string `json:"handle"`
CreatedAt *Timestamp `json:"created_at"`
UpdatedAt *Timestamp `json:"updated_at"`
Groups []*Group `json:"groups,omitempty"`
Members []*Member `json:"member,omitempty"`
}

// Helper types for JSONUnmarshal
type program Program // Used to avoid recursion of JSONUnmarshal
type programUnmarshalHelper struct {
program
Attributes *program `json:"attributes"`
Attributes *program `json:"attributes"`
Relationships struct {
Groups struct {
Data []*Group `json:"data"`
} `json:"groups"`
Members struct {
Data []*Member `json:"data"`
} `json:"members"`
} `json:"relationships"`
}

// UnmarshalJSON allows JSONAPI attributes and relationships to unmarshal cleanly.
Expand All @@ -50,5 +60,7 @@ func (p *Program) UnmarshalJSON(b []byte) error {
return err
}
*p = Program(helper.program)
p.Groups = helper.Relationships.Groups.Data
p.Members = helper.Relationships.Members.Data
return nil
}
44 changes: 44 additions & 0 deletions h1/program_service.go
@@ -0,0 +1,44 @@
// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package h1

import (
"fmt"
)

// ProgramService handles communication with the program related methods of the H1 API.
type ProgramService service

// Get fetches a Program by ID
func (s *ProgramService) Get(ID string) (*Program, *Response, error) {
req, err := s.client.NewRequest("GET", fmt.Sprintf("programs/%s", ID), nil)
if err != nil {
return nil, nil, err
}

rResp := new(Program)
resp, err := s.client.Do(req, rResp)
if err != nil {
return nil, resp, err
}

return rResp, resp, err
}

0 comments on commit bc8cb11

Please sign in to comment.